open函数使用一个文件名作为唯一的强制参数,然后返回一个文件对象。
一 r 模式与 rb 模式的区别
r 模式,需要指定编码,windows下默认是gbk编码。rb模式直接读取二进制,与编码没有关系,加上就报错。
with open('1.txt','rb') as f: data=f.read() print(data,type(data))
输出:
b'\xe4\xbc\x98\xe9\x85\xb7\n' <class 'bytes'>
如果在 rb模式下,强行加上encoding,报错。
with open('1.txt',encoding='utf-8',mode='rb') as f: data=f.read() print(data,type(data))
报错信息:
ValueError: binary mode doesn't take an encoding argument
一般情况下要指定encoding,windows下默认是gbk,如果保存的时候是gbk,不加上encoding是可以的。
以下代码是在windows下运行。
with open('1.txt','r') as f: data=f.read() print(data,type(data))
输出:
优酷 <class 'str'>
因为文件1.txt,我是以gbk编码格式保存的。
二 w 模式与 wb 模式
与 r 模式 和 rb 模式类似,b指的就是bytes类,所以采用 wb模式,写入的必须是bytes格式。同样不要指定encoding,否则会报错!
with open('1.txt',encoding='utf-8',mode='wb') as f: f.write('中国'.encode(encoding='utf-8'))
报错信息:
ValueError: binary mode doesn't take an encoding argument
更改如下:
with open('1.txt',mode='wb') as f: f.write('中国'.encode(encoding='utf-8'))
没有报错,正常写入。b 模式下,一定要写入bytes格式!!!!
总结: b 模式下,一定要注意,不要写encoding模式,一定不要!!!!!
三 文件方法:
'+'参数可以用到其他任何模式中,指明读和写都是允许的。
b 模式一般是用于声音剪辑或者图像,原理比较复杂。
1 f.read() 可以传整数格式的参数,在不同模式下,整数的含义并不一样。
在 r 模式下,代表的是一个字符。因为我在1.txt中写的是汉字,所以输出结果是3.,代表3个字节。如果文件中是数字或者字母,返回的则是 1 。
with open('1.txt',encoding='utf-8',mode='r+') as f: f.read(1) print(f.tell())
输出:3
在 rb 模式下,代表的是一个字节,所以不管是一个汉字还是数字还是字母,返回的都是 1 。
with open('1.txt',mode='rb+') as f: f.read(1) print(f.tell())
输出:1
2 seek方法:
Change the stream position to the given byte offset。
指定指针位置,两个参数,第一个参数表示移动的 字节数,特别强调,是字节数。 。 第二个参数。0代表从文件开始位置,1 代表从文件当前位置,2 代表从文件末尾,可以省略,默认是0
Move to new file position and return the file position. Argument offset is a byte count. Optional argument whence defaults to SEEK_SET or 0 (offset from start of file, offset should be >= 0); other values are SEEK_CUR or 1 (move relative to current position, positive or negative), and SEEK_END or 2 (move relative to end of file, usually negative, although many platforms allow seeking beyond the end of a file). Note that not all file objects are seekable
seek方法的应用:
f=open('1.txt',mode='r+',encoding='utf-8') f.write('dsdfdfsd') # f.seek(0) a=f.read() f.close() print(a)
在注释掉f.seek()后,输出 空。
注意:
当文件是以 r 模式打开时,seek方法只支持第二个参数为 0,强行从当前位置,或者末尾位置会报错。
只有文件以 b 模式打开,seek方法才允许 偏移位置从当前位置(参数为1)或者从末尾位置(参数为2)开始。
举例:
f=open('1.txt',mode='r+',encoding='utf-8') f.seek(-6,2) print(f.tell()) f.truncate() f.close()
会报错:
io.UnsupportedOperation: can't do nonzero end-relative seeks
换成 b 模式就可以了。
f=open('1.txt',mode='rb+') f.seek(-6,2) print(f.tell()) f.truncate() f.close()
正常运行
f=open('1.txt',mode='r+',encoding='utf-8') f.write('hello world') f.seek(0) a=f.read() f.close() print(a)
f.seek()没被注释的情况下,输出‘hello world’。
输出:
hello world
总结:
f.write()调用后,光标移到了white所写的内容末尾。
f.read()是从光标开始的位置开始读取。
要有这两个概念,所以上述两个例子,就说明了这个问题,也把seek方法的作用展示出来了。
3 truncate方法:用于截断文件,如果指定了可选参数 size,则表示截断文件为 size 个字符,指的是从文件开头截取size字节大小的字符串,注意是字节大小,其余的都删掉,这种情况下,不会考虑光标在什么位置。 如果没有指定 size,则从当前光标位置起截断,光标后面的字符串都被删掉。
四 重中之重!
with open('1.txt',encoding='utf-8',mode='r+') as f: for line in f: #非常经常的会遇到,会使用到。 print(line)
l=[] from collections import Iterable with open('1.txt',encoding='utf-8',mode='r+') as f: #文件句柄 f 是可迭代对象,单论这一点和列表,字符串,字典,元组没什么区别。所以可以 for line in f:line取到的是字符串格式。 print(f,type(f)) print(isinstance(f,Iterable)) print(isinstance(l,Iterable))
五 类文件
类文件对象是支持一些file类方法的对象,最重要的是支持read方法或者write方法。类文件对象,有时成为 流。
比如sys模块中的 sys,stdin sys.stdout sys.stderr
六
1 关于 f 的说明
f=open('1.txt','w',encoding='utf-8') f.write('123') f.close() print(f) f.read()
输出:
<_io.TextIOWrapper name='1.txt' mode='w' encoding='utf-8'> Traceback (most recent call last): File "D:/Program Files/JetBrains/s7/day29/client1.py", line 23, in <module> f.read() ValueError: I/O operation on closed file.
解释器打开文件,解释器内存中存执 f ,这个就是一个单纯的变量名。
打开的文件是在计算机内存中,文件的打开与关闭涉及到硬件底层,这是由操作系统来干的,不可能有解释器执行。打开的文件是在计算机内存中。f.close()是系统调用,告诉操作系统这个文件已经没用的,可以关闭了。
但 f 这个变量名还是在python解释器的内存中。不过,此时,再用 f 去调用 read 方法,就会报错,因为在内存中的文件已经没有了。
2 关于f=open(filename,encoding='utf-8')
为什么指定encoding,因为 f =open ,只是有python提出系统调用,但真正执行打开操作的是操作系统。所以encoding是给操作系统设定的。一句话,open,send,close,是系统调用,真正执行时操作系统,因为涉及到底层硬件。
来源:https://www.cnblogs.com/654321cc/p/7422773.html