《Python核心编程》第九章:文件和输入输出

本章大纲

本章介绍了文件对象(内建函数、内建方法、属性), 标准文件, 访问文件系统的方法, 文件执行,初步认识持久存储和标准库中与文件有关的模块。

知识点

9.1 文件内建函数

9.1.1 open()

open() 的基本语法:
file_object = open(file_name, access_mode='r', buffering=-1)

所有 POSIX 兼容系统, 包括 Linux , 都会忽略 “b” 二进制访问模式。

9.1.2 file()

建议使用 open() 来读写文件, 而在处理文件对象时使用 file() , 例如: if instance(f, file)

9.2 文件内建方法

9.2.1 输入

file.xreadlines() 不是一次性读取取所有的行, 而是每次读取一块, 所以用在 for 循环时可以减少对内存的占用,和使用 iter(file)for eachLine in file 的效果是一样的。

9.2.2 输出

  • 输入方法 read() 或者 readlines() 从文件中读取行时, Python 并不会删除行结束符;
  • 输出方法 write()writelines() 不会自动加入行结束符,需要在向文件写入数据前自行加入行结束符。

9.2.3 文件内移动

  • seek(offset=0):在文件中移动文件指针到不同的位置. offset 字节代表相对于某个位置偏移量。
  • tell():返回当前位置的偏移量。
  • truncate(size=file.tell()):截取文件到最大 size 字节, 默认为当前文件位置

9.2.4 os 模块内建方法

  • os.linesep():行分隔符
  • os.sep():路径名分隔符

9.3 文件内建属性

  • f.closed
  • f.mode
  • f.encoding
  • f.name

9.4 标准文件

  • 标准输入:sys.stdin
  • 标准输出:sys.stdout
  • 标准错误:sys.stderr

9.5 commandline参数

  • argc 和 argv 分别代表参数个数(argument count)和参数向量(argument vector).
  • sys.argv[0] 是程序的名称.
  • 处理命令行参数的模块:getopt模块、optparse模块

9.6 文件系统

9.6.1 os 模块

  • read()/write() 根据文件描述符读取/写入数据
  • remove()/unlink() Delete file 删除文件
  • mkdir()/makedirs() 创建目录/创建多层目录
  • rmdir()/removedirs() 删除目录/删除多层目录

9.6.2 os.path 模块

  • basename() 去掉目录路径, 返回文件名
  • dirname() 去掉文件名, 返回目录路径
  • exists() 指定路径(文件或目录)是否存在
  • isabs() 指定路径是否为绝对路径
  • isdir() 指定路径是否存在且为一个目录
  • isfile() 指定路径是否存在且为一个文件
  • islink() 指定路径是否存在且为一个符号链接

9.7 永久存储模块

9.7.1 pickle 和 marshal 模块

  1. marshal 和 pickle 模块可以实现最小化永久性转换并储存 Python 对象.
  2. 数据的序列化(扁平化、顺序化):将(复杂)对象转换为一个二进制数据集合的过程, 使之可以将数据集合保存起来或通过网络发送。
  3. 数据的反序列化:把二进制数据集合恢复原来的对象格式的过程。
  4. cPickle 是 pickle 的一个更快的 C 语言编译版本.

marshal 和 pickle 模块的区别:

  • marshal 只能处理简单的 Python 对象(数字, 序列, 映射, 以及代码对象)
  • pickle 可以处理递归对象, 被不同地方多次引用的对象, 以及用户定义的类和实例

9.7.2 DBM 风格的模块

  • db系列的模块使用传统的DBM格式写入数据:只能储存字符串,不能对Python对象进行序列化。
  • DBM的多种实现:dbhash/bsddb,dbm,gdbm,以及dumbdbm等,这些模块为对象提供了一个命名空间,这些对象同时具备字典对象和文件对象的特点。

9.7.3 shelve 模块

  • shelve模块使用anydbm模块寻找合适的DBM模块,然后使用cPickle来完成对储存转换过程。
  • shelve模块允许对数据库文件进行并发的读访问,但不允许共享读/写访问。
  • shelve模块提供了字典式的文件对象访问功能, 进一步减少工作.

shelve模块与储存转换模块、永久性储存模块之间的关系:
《Python核心编程》第九章:文件和输入输出_第1张图片

9.8 相关模块

  • base64 提供二进制字符串和文本字符串间的编码/解码操作
  • binascii 提供二进制和 ASCII 编码的二进制字符串间的编码/解码操作
  • glob/fnmatch 提供 Unix 样式的通配符匹配的功能
  • fileinput 提供多个文本文件的行迭代器
  • getopt/optparse 提供了命令行参数的解析
  • tarfile 读写 TAR 归档文件, 支持压缩文件
  • gzip/zlib 读写 GNU zip( gzip) 文件(压缩需要 zlib 模块)
  • bz2 访问 BZ2 格式的压缩文件
  • zipfilec 用于读取 ZIP 归档文件的工具

练习

9–1. 文件过滤. 显示一个文件的所有行, 忽略以井号( # )开头的行. 这个字符被用做 Python , Perl, Tcl, 等大多脚本文件的注释符号. 附加题: 处理不是第一个字符开头的注释.

for line in open('test.txt'):
    if line is not None and line[0] != '#':
        print line,

9–2. 文件访问. 提示输入数字 N 和文件 F, 然后显示文件 F 的前 N 行.

略。

9–3. 文件信息. 提示输入一个文件名, 然后显示这个文本文件的总行数.

sum(1 for x in open('test.txt'))

9–4. 文件访问. 写一个逐页显示文本文件的程序. 提示输入一个文件名, 每次显示文本文件的 25 行, 暂停并向用户提示”按任意键继续”, 按键后继续执行.
略。

9–5. 考试成绩. 改进你的考试成绩问题(练习 5 -3 和 6-4), 要求能从多个文件中读入考试成绩. 文件的数据格式由你自己决定.

略。

9–6. 文件比较. 写一个比较两个文本文件的程序. 如果不同, 给出第一个不同处的行号和列号.

略。

9–7. 解析文件. Win32 用户: 创建一个用来解析 Windows .ini 文件的程序. POSIX 用户: 创建一个解析 /etc/serves 文件的程序. 其它平台用户: 写一个解析特定结构的系统配置文件的程序.

思路:忽略以#号开头的行,类似9-1。

9–8. 模块研究. 提取模块的属性资料. 提示用户输入一个模块名(或者从命令行接受输入). 然后使用 dir() 和其它内建函数提取模块的属性, 显示它们的名字, 类型, 值.

import importlib

def get_module_attr(module_name) :
    module = importlib.import_module(module_name) # module = __import__(m)
    attrs = dir(module)
    res = []

    for attr in attrs:
        value = getattr(module, attr)
        res.append({'name':attr, 'type':type(value), 'value':value})
    return res

for attr in get_module_attr('math'):
    print 'name: %s\t type: %s\t value: %s' % (attr['name'], attr['type'], attr['value'])

9–9. Python 文档字符串. 进入 Python 标准库所在的目录. 检查每个 .py 文件看是否有 _doc_ 字符串, 如果有, 对其格式进行适当的整理归类. 你的程序执行完毕后, 应该会生成一个漂亮的清单. 里边列出哪些模块有文档字符串, 以及文档字符串的内容. 清单最后附上那些没有文档字符串模块的名字. 附加题: 提取标准库中各模块内全部类(class)和函数的文档.

import os
import importlib
from warnings import catch_warnings

pymodules = {}
path = r'D:\Python27\Lib'
suffix = '.py'

pyfiles = [f for f in os.listdir(path) if f.endswith(suffix)]
for f in pyfiles:
    # splitext return: (filename, extension)
    module_name = os.path.splitext(f)[0]
    try:
        module = importlib.import_module(module_name)
        pymodules[module_name] = module.__doc__
    except ImportError, e:
        continue

hasdoc = []
nodoc = []
for module in pymodules:
    if pymodules[module]:
        hasdoc.append(module)
    else:
        nodoc.append(module)

print 'module has no doc:'
for key in nodoc:
    print key + '|',

print '*' * 50

print 'module has doc:'
for key in hasdoc:
    print '[', key, ']'
    print pymodules[key]
    print '-' * 30

9–10. 家庭理财. 创建一个家庭理财程序. 你的程序需要处理储蓄, 支票, 金融市场, 定期存款等多种帐户. 为每种帐户提供一个菜单操作界面, 要有存款, 取款, 借, 贷等操作. 另外还要提供一个取消操作选项. 用户退出这个程序时相关数据应该保存到文件里去(出于备份的目的, 程序执行过程中也要备份.)

略。

你可能感兴趣的:(python)