首页 > 代码库 > python基础之字符编码及文件操作
python基础之字符编码及文件操作
一、了解字符编码前的知识储备
1、计算机运行程序或读取文件的原理
为了使计算机运行速度不被I/O操作速度拖慢,CPU并不会直接从硬盘中读取数据,因为硬盘的读写速度和CPU相差太大,所以CPU都是从速度相对较快的内存中读取数据的。而程序文件和文本文件为了永久保存又都保存在硬盘中,因此计算机运行程序或读取文件的过程一般是这样的,先由操作系统控制硬盘将程序文件或文本文件读取到内存中,然后CPU再从内存中读取数据运行或者输出到终端打印到屏幕上。
2、文本编辑器读取文件原理
2.1文本编辑器程序文件读取到内存中运行
2.2 将文本文件读取到文本编辑器所在内存空间
2.3 文本编辑器将读取到内存中的文本文件内容打印到终端
3、python解释器运行原理
3.1 python解释器程序文件读取到内存中运行
3.2 python程序文件读取到python解释器所在内存空间
3.3 python解释器解释执行python程序文件中的代码
所以文本编辑器和python解释器在读取python程序文件时的过程是一样的,而python程序文件在没有被执行之前和普通文本文件也没有区别,不一样的是文本编辑器读取python程序文件是为了打印到终端显示,python解释器则是为了解释执行python代码,也是在这一步python程序文件中的内容才有了代码的意义。
二、什么是字符编码
文件中的那些字符是人能识别的,计算机只能识别二进制数,那如何让文件中那些人能识别的字符可以被计算机识别呢,即如何把字符转换为二进制数,这就用到了字符编码。字符编码就是把字符对应到一个特定的数字上,有了字符编码这种字符到数字的对应关系之后,只需要再把这些数字转换成二进制数就可以让计算机识别那些人才能识别的字符啦。
而计算机中能用到字符编码的场景只有以下两种:
1、文本文件包括程序代码文件被存取的时候
2、程序文件中的字符串被定义和使用时
三、Unicode和UTF-8
字符编码在最开始的时候只有ASCII码,专门用于识别英文字母和一些特殊符号,用1Bytes代表一个字符,之后计算机普及了各国都有了自己的字符编码,为了给字符编码一个统一标准以便各国的程序互相可以正常运行就出现了Unicode万国码,它兼容所有国家的语言,Unicode规定所有语言都用2Bytes代表一个字符。然而这就是存储英文文件的空间无故多了一倍,所以为了节省这部分空间就出现了UTF-8,它规定存储英文用1Bytes代表一个字符,其余都用3Bytes代表一个字符。
Unicode因为简单粗暴的规定所有国家的语言都用2Bytes代表一个字符,没有判断英文字符的时间,所以转换速度更快,在内存中同一使用Unicode编码格式存储字符
UTF-8因为在存储英文上更节省空间,并且用于判断英文字符的时间远小于硬盘I/O速度和网络延迟,所以在硬盘存储和网络传输中都使用的是UTF-8编码格式
四、字符编码间的转换
4.1、转换关系
Unicode-------》encode------》其他编码格式
其他编码格式-----》decode--------》Unicode
1)encode、decode必须使用相同的字符编码,否则就会乱码
2)在encode和decode时需要说明编码和解码的字符编码,这里说的字符编码指的是文件使用的编码格式
4.2、默认编码
python3中默认文件存取的字符编码是UTF-8,默认的字符串编码格式为Unicode
python2中默认文件存取的字符编码是ASCII,默认的字符串编码也是ASCII并且存储形式是encode后的bytes类型,可以在字符串前加u使编码格式变为Unicode,比如u‘你好啊‘
Windows系统的默认字符编码为gbk
4.3、乱码
因为文件在内存和硬盘间有存取两种操作方式,所以乱码的产生也有两种情景
1)乱码产生于文件保存时
由于在文件保存时使用了不合适的字符编码格式导致文件无法正确保存,导致文件乱码,这种乱码实际上文件已经损坏。比如文件内容都是中文,但保存时使用了日文的字符编码就会造成这一种情况。
2)乱码产生于文件读取时
由于读取文件时使用了和文件保存时不一样的字符编码,使文件无法正常显示,这种乱码是可以解决的,只需要使用正确的字符编码即可。
4.4、python指定程序执行使用的编码格式
我们在保存python文件时可能使用其他编码格式,为了不让解释器使用默认编码格式运行程序导致报错,就需要提前告诉解释器应该使用何种编码格式运行自己的程序,方法很简单就是在代码的第一行写上#coding:文件编码格式
4.5、程序执行时的字符编码问题
由于内存中同一使用Unicode,所以所有文件在读入内存时都是Unicode编码格式,而在程序遇到字符串定义时会在内存中再开辟内存去存放字符串一般这时候还是以Unicode编码格式存放,但也可以指定其他格式
4.6、python2和python3的区别
python2中字符串有两种定义格式,1 name=‘alex‘,这种格式定义的字符串在内存中存储时是以encode后的bytes类型存在内存中的,因为在python2中定义bytes=str,而encode时的字符编码就是文件头指定的编码格式或者不指定就是 python2默认的ASCII;2 name=u‘alex‘,这种格式定义的字符串在内存中就是以Unicode编码格式存放的
python3中也有两种字符串定义格式,1name=‘alex‘,这种格式定义的字符串在python3中直接就是Unicode编码格式存放的;2 s=‘alex‘,s1=s.encode(‘utf-8‘),s1就是python3中的bytes类型数据了
五、字符编码的结论
1、encode用什么编码,decode就用什么解码
2、bytes类型是Unicode编码后的数据,bytes类型想看到信息就要decode成Unicode
3、在硬盘存储数据和网络传输中必须是bytes类型的数据
六、文件操作
1)打开文件
python中打开文件使用open函数,比如open(r‘文件路径‘,‘打开文件的模式‘,encodig=‘文件使用的字符编码‘)。open函数中的三个参数分别为:
文件路径:指定需要操作的文件的路径,一般在文件路径前加r,使一些特殊的符号比如\t,\n等变成普通字符
文件打开模式:常用的模式有r只读模式,文件只能查看内容不能往里面添加内容,文件打开后光标在文件开头;w只写模式,文件只能往里面添加内容不能查看,且会清空文件原本的内容,文件打开后光标在文件开头;a追加模式,只能在文件末尾追加内容,不能查看,文件打开后光标在文件末尾;rb、wb、ab在前面三种模式基础上加上b表示文件以二进制形式被操作,不需要考虑编码格式,适用于任何文件。如果不指定文件打开模式,默认以只读模式打开。
文件使用的字符编码:打开文件时说明文件保存时使用的是何种字符编码,不指定则默认为utf-8
文件打开后会获得一个文件句柄,需要将它赋值给一个变量以便后续对文件进行操作。
2)读文件
f.read():将文件的全部内容以一个字符串形式返回,也可以指定读取文件的长度如,f.read(3)表示读取文件中从开头位置到第三个字符处的内容
f.readline:每次调用只读取文件的一行内容,以字符串形式返回
f.readlines:将文件的全部内容以一个列表的形式返回,文件的每一行内容作为列表的一个元素,并且为字符串形式
for循环输出文件内容:
for line in f:
print(line)
以上是读取文件最快的方式,因为在内存中同时只会有文件的一行内容
3)写文件
f.write:向文件中写入一行数据
f.writelines:向文件中写入多行数据,以列表的形式传入如,f.writelines([‘1111‘,‘aaaa‘,‘dddd‘])表示写入三行数据分别为‘1111’,‘aaaa’,‘dddd‘
4)关闭文件
f.close:向操作系统发起关闭文件的请求,此时f的文件句柄还在但是已经无法操作文件
5)文件的其他操作
1、上下文管理
python中为了防止程序员忘记关闭文件提供了一种便捷的函数即with函数,它可以在文件操作完之后自动关闭文件,并且在打开文件时可以同时打开多个文件,比如with open(‘a.txt‘,‘r‘,encoding=‘utf-8‘) as read_f,\
open(‘a.txt.swap‘,‘r‘) as write_f:
2、光标移动
seek:将光标移动到指定位置,比如f.seek(0)表示将光标移动到文件开头位置
tell:返回光标当前所处位置
truncate:截断文件,除了指定位置的内容其余都清除,比如f.truncate(3)表示保留文件开头到第三个字符处的内容,其余都被清除
3、强制将内存的数据写入硬盘
f.flush:强制将内存中的数据立即写入硬盘而不等待系统写入
4、文件修改
python中要修改一个文件的内容一般都是打开源文件,再打开一个空白文件,一边从源文件读一边写入空白文件然后把需要修改的行修改之后写入空白文件,最后把源文件删除再把新建的文件重命名为之前的文件名。
python基础之字符编码及文件操作