读写文件
open()
返回一个文件对象,最常见的用法带有两个参数:open(filename, mode)
具体参数参考:https://www.cnblogs.com/IMWU/p/10947262.html
>>> f = open('workfile', 'w')
文件对象的方法
要读取文件内容,可以调用f.read(size)
,该方法读取若干数量的数据并以字符串(在文本模式中)或字节对象(在二进制模式中)形式返回它。size 是可选的数值参数。当 size被省略或为负数时,将会读取并返回整个文件;若文件大小是你机器内存的两倍,那是你自己的问题。否则,至多读取和返回 size 大小的字节数据。如果到了文件末尾,f.read()
会返回一个空字符串(""
)。
>>> f.read() 'This is the entire file.\n' >>> f.read() ''
f.readline()
从文件读取一行数据;字符串结尾会带有一个换行符 (\n
) ,只有当文件最后一行没有以换行符结尾时才会省略。这样返回值就不会有混淆;如果f.readline()
返回一个空字符串,那就表示已经达到文件的末尾,而如果返回一个只包含一个换行符的字符串'\n'
,则表示遇到一个空行。
>>> f.readline() 'This is the first line of the file.\n' >>> f.readline() 'Second line of the file\n' >>> f.readline() ''
你可以循环遍历文件对象来读取文件中的每一行。这让内存高效,快速,并简化代码:
>>> for line in f: ... print(line, end='') ... This is the first line of the file. Second line of the file
如果你想要读取文件列表中所有行的数据,你也可以使用 list(f)
或 f.readlines()
。
f.write(string)
将 字符串 的内容写入到该文件,返回写入的字符数。
>>> f.write('This is a test\n') 15
其他类型的对象,在写入之前则需要转换成 字符串 (在文本模式下) 或 字节对象 (以二进制模式)
>>> value = ('the answer', 42) >>> s = str(value) # convert the tuple to string >>> f.write(s) 18
f.tell()
返回一个整数,代表文件对象在文件中的当前的位置,在二进制模式中该数值表示自文件开头到指针处的字节数,在文本模式中则是不准确的。
若要更改该文件对象的位置,可以使用f.seek(offset, from_what)
。位置由参考点加上offset 计算得来;参考点的选择则来自于from_what参数。当from_what的值为0,1,2 时,分别使用文件开头、当前文件位置和文件结尾作为参考点。from_what 可以省略,默认值为 0,表示以文件的开始作为参考点。
>>> f = open('workfile', 'rb+') >>> f.write(b'0123456789abcdef') 16 >>> f.seek(5) # Go to the 6th byte in the file 5 >>> f.read(1) b'5' >>> f.seek(-3, 2) # Go to the 3rd byte before the end 13 >>> f.read(1) b'd'
在文本文件中(没有以b
模式打开的文件),只允许从文件的开始查找(有个例外是查找到文件的末尾seek(0, 2)
),而且offset只有是从f.tell()
返回的值或者是0才是合法的。其它任何偏移 值都会产生未定义的行为。
使用完一个文件后,调用f.close()
可以关闭它并释放其占用的所有系统资源。调用f.close()
后,再尝试使用该文件对象将自动失败。
>>> f.close() >>> f.read() Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: I/O operation on closed file
处理文件对象时使用with
关键字是很好的做法。这样做的好处在于文件用完后会自动关闭,即使过程中发生异常也没关系。它还比编写一个等同的try
-finally
语句要短很多:
>>> with open('workfile', 'r') as f: ... read_data = f.read() >>> f.closed True
使用json
存储结构化数据
从文件中读写字符串很容易。数值就要多费点儿周折,因为read ()
方法只会返回字符串,应将其传入int()
这样的函数,就可以将'123'
这样的字符串转换为对应的数值123。当你想要保存更为复杂的数据类型,例如嵌套的列表和字典,手工解析和序列化它们将变得更复杂。
标准模块json
可以接受 Python 数据结构,并将它们转换为字符串表示形式;此过程称为序列化。从字符串表示形式重新构建数据结构称为反序列化。
如果你有一个对象x
,你可以用简单的一行代码查看其JSON字符串表示形式:
>>> json.dumps([1, 'simple', 'list']) '[1, "simple", "list"]'
dumps()
函数的另外一个变体dump()
,直接将对象序列化到一个文本文件。所以如果f
是为写入而打开的一个文件对象,我们可以这样做:
json.dump(x, f)
为了重新解码对象,如果f
是为读取而打开的文本文件对象 :
x = json.load(f)
这种简单的序列化技术可以处理列表和字典,但序列化任意类实例为 JSON 需要一点额外的努力。Json
模块的手册对此有详细的解释。