with open用法
open方法
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None,
closefd=True, opener=None)
打开一个文件,返回一个文件对象(流对象)和文件描述符。打开文件失败,则返回异常
基本使用:创建一个文件test,然后打开它,用完关闭
f = open("test") # file对象 # windows <_io.TextIOWrapper name='test' mode='r' encoding='cp936'> # linux <_io.TextIOWrapper name='test' mode='r' encoding='UTF-8'> print(f.read()) # 读取文件 f.close() # 关闭文件
文件操作中,最常用的操作就是读和写。
文件访问的模式有两种:文本模式和二进制模式。不同模式下,操作函数不尽相同,表现的结果也不一
样。
注:
windows中使用codepage代码页,可以认为每一个代码页就是一张编码表。cp936等同于GBK。
模式对于IO操作来说,其实只有读和写两种:
只读 r
只写 w、x、a
增加缺失能力 +
r 模式
只读打开文件,如果使用write方法,会抛异常
如果文件不存在,抛出FileNotFoundError异常
w 模式
表示只写方式打开,如果读取则抛出异常
如果文件不存在,则直接创建文件
如果文件存在,则清空文件内容
x 模式
文件不存在,创建文件,并只写方式打开
文件存在,抛出FileExistsError异常
a 模式
文件存在,只写打开,追加内容
文件不存在,则创建后,只写打开,追加内容
wxa模式都可以产生新文件
w不管文件存在与否,都会生成全新内容的文件
a不管文件是否存在,都能在打开的文件尾部追加
x必须要求文件事先不存在,自己要造一个新文件
文本模式t
字符流,将文件的字节按照某种字符编码理解,按照字符操作。open的默认mode就是rt。
二进制模式b
字节流,将文件就按照字节理解,与字符编码无关。二进制模式操作时,字节操作使用bytes类型
+ 模式
为r、w、a、x提供缺失的读或写功能,但是,获取文件对象依旧按照r、w、a、x自己的特征。+模式不能单独使用,可以认为它是为前面的模式字符做增强功能的。
encoding:编码,仅文本模式使用
None 表示使用缺省编码,依赖操作系统。windows、linux下测试如下代码
f = open('test1','w') f.write('啊') f.close()
windows下缺省GBK(0xB0A1),Linux下缺省UTF-8(0xE5 95 8A)
文件指针
mode=r,指针起始在0
mode=a,指针起始在EOF
f = open('o:/test.txt', 'wb+') print(f) f.write(b'abc') print(f.tell()) f.close() f = open('o:/test.txt', 'rt+') # windows下打开 f.write('啊') # 从什么地方开始写几个字节? print(hex(ord('啊')), '啊'.encode(), '啊'.encode('gbk')) print(f.tell()) f.close()
read
read(size=-1)
size表示读取的多少个字符或字节;负数或者None表示读取到EOF
filename = 'o:/test.txt' f = open(filename, 'w+') f.write('马哥教育') f.close() f = open(filename) print(1, f.read(1)) # 按字符 print(2, f.read(2)) print(3, f.read()) f.close() f = open(filename, 'rb') print(4, f.read(1)) # 按字节 print(5, f.read(2)) print(6, '马哥教育'.encode('gbk')) print(7, f.read()) f.close()
建议,使用文件对象时,一定要指定编码,而不是使用默认编码
write
write(s),文本模式时,从当前指针处把字符串s写入到文件中并返回写入字符的个数;二进制时将
bytes写入文件并返回写入字节数
writelines(lines),将字符串列表写入文件
filename = 'o:/test.txt' f = open(filename, 'w+') lines = ['abc', '123\n', 'magedu'] # 需提供换行符 # for line in lines: # f.write(line) f.writelines(lines) f.seek(0) # 回到开始 print(f.read()) f.close()
close
flush并关闭文件对象。文件已经关闭,再次关闭没有任何效果。可以查看文件对象的closed属性(f.closed),判断
是否关闭
上下文管理
文件对象这种打开资源并一定要关闭的对象,为了保证其打开后一定关闭,为其提供了上下文支持。
filename = 'o:/test.txt' with open(filename) as f: print(1, f.closed) print(f.write('abcd')) # r模式写入失败,抛异常 print(2, f.closed) # with中不管是否抛异常,with结束时都会保证关闭文件对象
with 文件对象 as 标识符: # 等同于 标识符 = 文件对象 pass # 标识符可以在内部使用
上下文管理
1. 使用with关键字,上下文管理针对的是with后的对象
2. 使用with ... as 关键字
3. 上下文管理的语句块并不会开启新的作用域
文件对象上下文管理1. 进入with时,with后的文件对象是被管理对象
2. as子句后的标识符,指向with后的文件对象
3. with语句块执行完的时候,会自动关闭文件对象
filename = 'o:/test.txt' f = open(filename) with f: print(1, f.closed) print(f.write('abcd')) # r模式写入失败 print(2, f.closed) # with中不管是否抛异常,with结束时都会关闭文件对象
filename = 'o:/test.txt' f = open(filename) with f as f2: print(f is f2) # True
文件的遍历
类似于日志文件,文件需要遍历,最常用的方式就是逐行遍历。
filename = 'o:/test.txt' with open(filename, 'w') as f: f.write('\n'.join(map(str, range(101, 120)))) with open(filename) as f: for line in f: # 文件对象时可迭代对象,逐行遍历 print(line.encode()) # 带换行符