文件操作
字符编码
GB2312 使用两个字节表示一个汉字,一般windows的文件采用这种编码格式,EXCEL转换的csv也是GB2312,文件另存为可以查看编码格式
GBK 也是使用两个字节表示一个汉字。
Unicode 固然统一了编码方式,但是它的效率不高,比如 UCS-4(Unicode 的标准之一)规定用 4 个字节存储一个符号,那么每个英文字母前都必然有三个字节是 0,这对存储和传输来说都很耗资源。
将之前写有 abc123+-*\ 的文件用记事本另存为 unicode 会发现文件的体积大了一倍。(本来应该是 4 倍,windows 做了优化)
UTF-8 可以根据不同的符号自动选择编码的长短。比如英文字母可以只用 1 个字节就够了。utf-8 中汉字使用 3 个字节存储。
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
打开 file 并返回对应的 file object。 如果该文件不能被打开,则引发 OSError
file 是一个 path-like object,表示将要打开的文件的路径(绝对路径或者当前工作目录的相对路径),也可以是要被封装的整数类型文件描述符。
mode 是一个可选字符串,用于指定打开文件的模式。默认值是 'r' ,这意味着它以文本模式打开并读取。默认值是 'r' ,这意味着它以文本模式打开并读取。其他常见模式有:写入 'w' (截断已经存在的文件);排它性创建 'x' ;追加写 'a' (在 一些 Unix 系统上,无论当前的文件指针在什么位置,所有 写入都会追加到文件末尾)
encoding 是用于解码或编码文件的编码的名称。这应该只在文本模式下使用。默认编码是依赖于平台的(不 管 locale.getpreferredencoding() 返回何值),但可以使用任何Python支持的 text encoding
mode 的取值:
字符 意义
'r' 文本读取(默认)
'w' 文本写入,并先清空文件(慎用),文件不存在则创建
'x' 文本写,排它性创建,如果文件已存在则失败
'a' 文本写,如果文件存在则在末尾追加,不存在则创建
和 mode 组合的字符
字符 意义
'b' 二进制模式,例如:'rb'表示二进制读
't' 文本模式(默认),例如:rt 一般省略 t
'+' 读取与写入,例如:'r+' 表示同时读写
with open('test.txt', 'r', encoding='utf-8') as fb:
content = fb.read()
print(content)
相对路径与绝对路径
进行文件处理时经常会碰到相对路径和绝对路径的问题。
绝对路径好理解,它指定了文件在电脑中的具体位置,以 windows 电脑为例:
d:\lemon\课件\python入门.md
相对路径一般是指相对当前脚本的路径,比如上面的案例中的 test.txt 因为和当前脚本在同一个文件夹下,所以可以直接使用 test.txt 作为文件名来操作。
也可显式的表达当前路径 ./test.txt,./ 表示当前目录。
../ 表示上级目录,同理 ../../ 表示上上级目录,依此类推。
一般情况下项目本身的资源文件和脚本路径相对固定,为了不影响项目的移植性,必须使用相对路径。
如果需要读取操作系统中固定位置的系统文件一般使用绝对路径。
readline 从文件中读取一行;如果 f.readline() 返回一个空的字符串,则表示已经到达了文件末尾
readlines 以列表的形式返回文件中所有的行。
要从文件中读取行,还可以循环遍历文件对象。这是内存高效,快速的,并简化代码:推荐写法
with open('test.txt', 'r', encoding='utf-8') as fb:
for line in fb:
print(line)
任何文件都可以以二进制读的方式打开,读取 test.txt 的二进制内容。
mode=rb,不需要encoding参数
with open('test.txt', 'rb') as fb:
content = fb.read()
print(content)
在写模式后加 b 即是写二进制模式,这种模式下写入内容为字节数据。
读写文件:有时候需要能够同时读写文件,在模式后面加上 + 号即可给读模式添加写,给写模式添加读。
案例:python 处理解析 CSV 文件
读取csv文件并解析为嵌套列表
data = []
with open('鸢尾.csv', 'r', encoding='gbk') as f:
for line in f:
# 去掉换行符
line = line.strip()
data.append(line.split(','))
将数据写为csv文件
with open('test.csv', 'w', encoding='utf-8') as f:
for item in data:
f.write(','.join(item) + '\n')
open 函数返回的文件对象使用文件指针来记录当前在文件中的位置
read 方法
在读模式下,使用文件对象的 read 方法可以读取文件的内容。
它接收一个整数参数表示读取内容的大小,文本模式下表示字符数量,二进制模式下表示字节大小。
当以读的方式打开文件后文件指针指向文件开头,执行 read 操作之后,根据读取的数据大小指针移动到对应的位置
a 模式打开文件后文件指针指向文件末尾。
tell 方法
文件对象的 tell 方法返回整数,表示文件指针距离文件开头的字节数。
with open('test.txt', 'r', encoding='utf-8') as f:
print(f.tell())
content = f.read(3)
print(content)
print(f.tell())
seek 方法
通过文件对象的 seek 方法可以移动文件句柄
seek 方法接收两个参数:
offset 表示偏移指针的字节数
whence 表示偏移参考,默认为 0
0 表示偏移参考文件的开头,offset 必须是 >=0 的整数
1 表示偏移参考当前位置,offset 可以是负数
2 表示偏移参考文件的结尾,offset 一般是负数
注意文本模式下只允许从文件的开头进行偏移,也即只支持 whence=0
with open('test.txt', 'r', encoding='utf-8') as f:
print(f.read(3))
跳转到文件开头
f.seek(0)
再读取第一个字
print(f.read(1))
with open('test.txt', 'rb') as f:
读取文件最后的10字节
f.seek(-10,2)
print(f.read())