函数定义是:open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
打开文件 file
并返回一个文本对象,如果文件无法被打开(被占用、文件不存在)会引发 OSError
。
file
是文件的路径,可以使用相对路径和绝对路径。
mode
是文件的打开模式,默认是 'r'
模式,也就是读模式。支持的模式有下面三种:
主要模式(写模式的时候不能读,读模式不能写):
'r'
读模式,当文件存在,打开文件;文件不存在则报错;读取的时候从文件最前面开始读取
'w'
覆盖写模式,当文件存在,打开文件;文件不存在则新建一个文件并打开;写入的时候会先清空文件里的内容,再重头开始写入
'a'
追加写模式,当文件存在,打开文件;文件不存在则新建一个文件并打开;写入的时候会从文件的末尾开始写入,不会覆盖原有内容
'x'
新建写模式,当文件存在,产生报错;文件不存在则新建一个文件并打开;写入的时候从最前面开始写入
次要模式:
't'
文本模式,将文件作为文本文件打开,读取和写入的时候均以文本字符串的形式进行读写(默认模式)
'b'
二进制模式,将文件作为二进制文件打开,读取和写入的时候均以二进制的形式进行读写
附加模式:
'+'
可读可写模式,打开文件,并且可读可写
三种模式每样只能一种,不能写 'wtb'
这种;主要模式必须写,其他模式可以省略写。
buffering
设置缓冲模式,0 表示关闭缓冲;1 表示以行为单位缓冲(仅在文本模式下可用);大于 1 的其他整数则指定缓冲区大小(仅适用于二进制模式)
encoding
表示编码格式,当使用文本模式打开文件的时候,使用 encoding
的值作为编码解码策略,一般建议是 'utf-8'
,以便于支持各种文本字符
newline
决定如何解析来自流的换行符。 它可以为 None
, ''
, '\n'
, '\r'
和 '\r\n'
。
clossfd
为 False
且给出的不是文件名而是文件描述符,那么当文件关闭时,底层文件描述符将保持打开状态。如果给出的是文件名,则 closefd
必须为 True
(默认值),否则将触发错误。
opener
可以通过传递可调用的 opener
来使用自定义开启器。然后通过使用参数( file,flags )调用 opener
获得文件对象的基础文件描述符。 opener
必须返回一个打开的文件描述符(使用 os.open
as opener 时与传递 None
的效果相同)。
xxxxxxxxxx
import os
dir_fd = os.open('somedir', os.O_RDONLY)
def opener(path, flags):
return os.open(path, flags, dir_fd=dir_fd)
with open('spamspam.txt', 'w', opener=opener) as f:
print('This will be written to somedir/spamspam.txt', file=f)
os.close(dir_fd) # 不要泄漏文件描述符
打开的文件对象支持上下文管理器,因为文件对象定义了 __enter__
和 __exit__
方法:
xxxxxxxxxx
with open('text.txt', 'r', encoding='utf-8') as f:
print(f.read())
打开的文件对象支持遍历(用于读取模式),因为定义了 __iter__
和 __next__
方法:
xxxxxxxxxx
with open('text.txt', 'r', encoding='utf-8') as f:
for line in f:
print(line) # 遍历到的内容 line 是每一行
我们在 open()
函数调用之后,得到的对象是一个 io.TextIOWrapper
对象,这个对象继承自 io.TextIOBase
,而这个 io.TextIOBase
又继承自 io.IOBase
。他们之间的继承关系可以表示为 io.IOBase -> io.TextIOBase -> io.TextIOWrapper
。下文中将从最基础的基类 io.IOBase
来一步一步讲解到 io.TextIOWrapper
。
io.IOBase
类这个对象是 python 所有 IO 方式的基类,是一切 IO 操作的基础。这个类的默认实现是用这个类的对象来代表一个无法读取、写入、查找的文件,籍此以支持用户通过选择性的重写里面的默认方法,来自由定义 io.IOBase
对象的行为。
IOBase
支持迭代,因为其定义了 __next__
方法和 __iter__
。IOBase
还支持上下文管理器,也就是 with
关键字:
xwith open('text.txt', 'w') as f:
f.write("content")
readline(size=-1, /)
从流中读取并返回一行。如果指定了 size,将至多读取 size 个字节。
对于二进制文件行结束符总是 b'\n'
;对于文本文件,可以用将 newline 参数传给 open()
的方式来选择要识别的行结束符。
readlines(hint=-1, /)
从流中读取并返回包含多行的列表。可以指定 hint 来控制要读取的行数:如果(以字节/字符数表示的)所有行的总大小超出了 hint 则将不会读取更多的行。
0
或更小的 hint 值以及 None
,会被视为没有 hint。
请注意,在不调用 file.readlines()
的情况下可以使用 for line in file: ...
来遍历文件对象。
writelines(lines, /)
将行列表写入到流。 不会添加行分隔符,因此通常所提供的每一行都带有末尾行分隔符。
io.TextIOBase
类文本 IO 的基类,用于派生出所有的文本 IO 类及对象。继承自 io.IOBase
。在这个类里面重写并且额外新增了很多方法,下面将会对常用的属性和方法进行介绍。下面只介绍有别于父类的部分。
encoding
用于控制字符串数据的编码格式,一般将其设置为 utf-8
以便于支持各种字符。
newline
这个属性会影响到一次性写入多行的时候用什么字符作为行分隔符,属性的值可以是一个字符串、字符串元组或者 None
read(size=-1, /)
从文件中读取 size
个字符,当 size
是 -1 的时候表示读取整个文件。当遇到 EOF
的时候会停止读取并将结果返回。(EOF
表示文件结束标记符,出现在文件的结尾,用于表示文件内容结束)
readline(size=-1, /)
与父类不同之处是,当遇到 EOF 的时候会返回空字符串,可以利用这一点来判断是否停止读取。
xxxxxxxxxx
with open('text.txt', 'r') as f:
while text:=f.readline(): # text:=f.readline() 在将 f.readline 的返回值作为条件的同时,还会将返回值赋值到 text 变量中
print(text)
由于文件换行的时候,会在行末加换行符 \n
,所以当读取到空行的时候,由于还有下一行,所以读取到的是一个单独的换行符 '\n'
,这一点会有别于遇到 EOF 的情况。
write(s, /)
将字符串 s 写入到流并返回写入的字符数。
io.TextIOWrapper
类一个高级的文本缓冲输入输出流,是 open()
函数返回值的对象类型。
encoding 给出将被用于编码或解码流的编码格式。 该参数值默认为 locale.getencoding()
。 可以使用 encoding="locale"
来显式地指定当前语言区域的编码格式。
newline 控制行结束符处理方式。 它可以为 None
, ''
, '\n'
, '\r'
和 '\r\n'
。 其工作原理如下:
当从流读取输入时,如果 newline 为 None
,则将启用 universal newlines 模式。 输入中的行结束符可以为 '\n'
, '\r'
或 '\r\n'
,在返回给调用者之前它们会被统一转写为 '\n'
。 如果 newline 为 ''
,也会启用通用换行模式,但行结束符会不加转写即返回给调用者。 如果 newline 具有任何其他合法的值,则输入行将仅由给定的字符串结束,并且行结束符会不加转写即返回给调用者。
将输出写入流时,如果 newline 为 None
,则写入的任何 '\n'
字符都将转换为系统默认行分隔符 os.linesep
。如果 newline 是 ''
或 '\n'
,则不进行翻译。如果 newline 是任何其他合法值,则写入的任何 '\n'
字符将被转换为给定的字符串。