本页面是本系列网页的最后一个页面,后面会有一个包含了代码demo索引的目录页面。(如果情况允许,可能会出一个包含了内容页的长页面,或者是也有可能将Word版课堂笔记分享出来)
文件的本质,是一个二进制文件,文本文件是通过编码,转换为二进制储存在硬盘等介质中——如果相同我文本,使用了不同的编码,会得到不同的效果(对于英文字符,区别不大;但是,对于简体中文这种,非英文字符来说,可能会乱码,甚至报错)。
这个小节的目标,是理解编码的本质,正确(地使用Python这种计算机编程语言)读写文本文件。
在设置为“简体中文”的Windows操作系统中,系统默认采用“GBK”编码——英文字符使用ASCII码,一个汉字占2字节(一个字符)。
比如前面的示例代码:
f = open("file_test.txt", "wt")
f.write("abc\n尝试添加简体中文\nxyz")
f.close()
理论上来说,是26字节,而“UTF-8”编码,就是34字节。
另外,字符串里面的“正则表达式”(regular expression)在Python中,很重要,要专门去看看。
本系列教程页面,只是给读者提供一个了解Python语言的思路,不涉及“正则表达式”。相关教程较多,不在此赘述。
关于”GBK“和“UTF-8”这两种主流编码方式的区别,这里简单提一下。以字符串"abc我们"为例。
“abc我们”用两种编码方式,所占的存储空间不一样(GBK编码是7字节,UTF-8是9字节)。老师说了一个软件(BinView),可以查看“内码”——但是我个人感觉,还是下面的Python代码更好用(这里是IDLE的“Shell”模式):
>>> s = "abc我们"
>>> import urllib.request#导入爬虫模块
>>> for i in range(len(s)):
print(urllib.request.quote(s[i]),s[i],ord(s[i]))
a a 97
b b 98
c c 99
%E6%88%91 我 25105
%E4%BB%AC 们 20204
>>>
(注释:“urllib.request.quote”可以获得非英文字符“Unicode”码的十六进制数,就是汉字在网址中的样子)
然后就是“PyCharm”软件的编码设置——“File”→“Settings”→“Editor”→“File Encodings”,初学Python语言的时候,全部选择为“gbk”(中国大陆地区的字符编码习惯),目前只是先学习Python这门计算机编程语言,暂时不统一用“utf-8”(如果要长期接触计算机编程语言的话,需要统一用这种)。
这里说一个相关知识点,“open()”函数有一个“encoding”参数——这里要注意,如果写入和读取的编码不统一的话,会乱码。
作为了解,Python2使用“ASCII”编码(需要进行编码、解码操作),Python3使用“Unicode码”(由于兼容性好,而被称为“万国码”)。而Windows记事本的新建文本文件默认使用“ANSI”(可以理解为“GBK”编码的一种称呼),要国际化的话,可以去设置为“UTF-8”。
文件被打开后既可以执行写操作也可以进行读操作,从什么地方开始读写是可以控制的,这要求文件以读写的方式打开,同时使用一个文件指针指向文件字节流的位置,调整指针的位置就可以进行任意位置的读写了。
我们在这个小节,就是掌握文件的这种随意的读写方法。
在程序看来,文件就是由一连串的字节组成的字节流,文件的每个字节都有一个位置编号,一个有n个字节的文件字节编号依次为0、1、2、 ... n-1号,在第n字节的后面有一个文件结束标志EOF (End Of File),如下表所示,为文件的模型,其中标明了文件字节值,文件位置编号以及文件指针的关系
字节值 | 73 | 32 | 76 | 111 | 118 | 101 | 32 | 89 | 111 | 117 | 33 | EOF |
位置 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
指针 | ↑ |
这个文件11字节,这里的“EOF”类似于前面第二章第二节里面的“range()”函数中的“stop”(end)参数,只是作为结束信号,而不出现在结果中。感觉很像ASCII码为3的“ETX”(end of text,正文结束)
文件的操作就是打开这样一个文件流, 对各个字节进行读写操作,操作完后关闭这个流,保存到磁盘。文件操作有下列三个基本步骤:
文件是一个字节流,读写哪个字节必须要指定这个字节的位置,这是由文件指针来决定的。如字节流有n个字节,p是指针的位置(0<=p<=n-1),那么读写的规则如下:
(遗传信息由DNA转换到RNA的过程称为“转录”)
关于指针操作,Python使用tell函数获取当前文件指针的位置,方法是:
文件对象.tell()
它返回一个整数。
看示例代码:
f = open("abc4.txt", "wt") # 新建一个空白文件(0字节)
print(fobj.tell()) # 指针位置为0
f.write("abc") # 写入ASCII字符
print(fobj.tell()) # 字节编号从零开始,但是写入完成后,指针位置是3
f.write("我们") # 写入非ASCII字符
print(fobj.tell()) # 这个时候,指针位置为7
f.close()
Python中使用feek函数来移动文件指针,方法是:
文件对象.seek(offset[, whence])
offset:开始的偏移量,也就是代表需要移动偏移的字节数(比如说,在上面的“表7.4.1”中,如果当前位置为“2”,想移动到5,只需要将这个参数设置为“3”);
whence:可选参数,默认值为0,给offset参数一个定义,表示要从哪个位置开始偏移:
在前面讲的文本文件打开模式中我们不能移动文件指针,如果在打开方式后面附加“加号”(+),那么这样的文件就是可以移动文件指针的,打开模式如下:
文件的本质是二进制字节数据,即所有的文件都是二进制文件,文本文件只是在读写时做了编码转换,教学目标是掌握二进制数据的读写操作。
“编码转换”是“GBK”和“utf-8”互相转换。
什么是二进制文件?实际上所有文件都是二进制文件,因为文件的存储就是一串二进制数据。文本文件也是二进制文件,只不过存储的二进制数据能通过一定的编码转为我们认识的字符而已。
比如说,“表7.4.1”的数据,我们看到的是
“****”(a-i-shi-te-ru,嗯,不对,是“***”,咦我在说什么?为什么被屏蔽了?)
而储存的内容,则是:
01001001 00100000 01001100 01101111 01110110 01100101 00100000 01011001 01101111 01110101 00100001
二进制文件在打开模式中使用小写字母“b”(bit)来表示,模式如下:
二进制文件认为数据都是字节流,因此二进制文件不存在编码的问题,只有文本文件才有编码问题。
因为二进制文件是字节流,因此也不存在readline、readlines读一行或者多行的操作函数,一般二进制文件值使用read函数读取,使用write函数写入。
“二进制文件不存在编码的问题”是因为有文件后缀名,而文本文件,只有一个“.txt”(代码文件有专属后缀名,这里不讨论)。
文件的本质是二进制字节数据,即所有的文件都是二进制文件,文本文件只是在写时把文本按一定编码转为二进制数据进行存储,在读时先读出二进制数据,再通过一定的编码转为文本。
重点是编码、指针、二进制。遇到问题,要多用搜索引擎(本来,在当前世界上最主流的搜索引擎是谷歌,但是谷歌被“墙”了,就不说了——还是去https://www.baidu.com),考验“搜商”。
第37堂课,简单了解了Python文件操作的主要原理,包括文件编码、文件指针、二进制文件。
本页面(?p=37)的实际上课时间为2020年5月22日第3小节课。
后面的课堂内容是“Python数据库操作”,就不再继续发出来了。
最后,Python基础知识就结束了,而这一门计算机编程语言,后面还有很多方面的应用,比如说数据分析(这个是教学计划)、人工智能、网页编程,这三个大方向比较出名。
原文:https://www.cnblogs.com/Robot-DX3906/p/13097507.html