Python-十二、读写计算机文件
1.编码
编码的本质就是让只认识0和1的计算机,能够理解我们人类使用的语言符号,并且将数据转换为二进制进行存储和传输。
这种从人类语言到计算机语言转换的形式,就叫做编码表,它让人类语言和计算机语言能够一一对应起来。
1.1二进制
由于有二进制,0和1这两个数字才能像“太极生两仪,两仪生四象,四象生八卦”一样,涵盖容纳世间所有的信息。
举例:
烽火与二进制现在有两座烽火台,右边为第1座,左边为第2座。我们约定,当没有烽火台被点着的时候,表示没有敌人(00);只点着第一座烽火台的时候,表示来了一个敌人(01);只点着第二座烽火台的时候,表示来了2个敌人。(10,逢二进一)
当两座烽火台都被点着的时候(11),就表示来了3个人。
用来存放一位0或1,就是计算机里最小的存储单位,叫做【位】,也叫【比特】(bit)。我们规定8个比特构成一个【字节】(byte),这是计算机里最常用的单位。
bit位/比特:存放一位二进制数,即0或1,最小的存储单位。
byte子节:8个二进制位为一个子节(B),最常用的单位。
1B(byte) = 8bit
1KB(Kilobyte 千字节) = 1024B
1MB(Megabyte 兆字节 简称“兆”) = 1024KB
1GB(Gigabyte 吉字节 又称“千兆”) = 1024MB
1.2编码表
计算机一开始发明的时候,只是用来解决数字计算的问题。后来人们发现,计算机还可以做更多的事,正所谓能力越大,责任越大。但由于计算机只识“数”,因此人们必须告诉计算机哪个数字来代表哪个特定字符。
于是除了0、1这些阿拉伯数字,像a、b、c这样的52个字母(包括大小写),还有一些常用的符号(例如*、#、@等)在计算机中存储时也要使用二进制数来表示,而具体用哪些二进制数 字表示哪个符号,理论上每个人都可以有自己的一套规则(这就叫编码)。
但大家如果想要互相沟通而不造成混乱,就必须使用相同的编码规则。如果使用了不同的编码规则,那就会彼此读不懂,这就是“乱码”的由来。
编码演进表1.3encode()和decode()
编码,即将人类语言转换为计算机语言,就是【编码】encode();反之,就是【解码】decode()。它们的用法如下代码表示:
print('小张'.encode('utf-8'))
print('小张'.encode('gbk'))
print(b'\xe5\x90\xb4\xe6\x9e\xab'.decode('utf-8'))
print(b'\xce\xe2\xb7\xe3'.decode('gbk'))
# 输出结果
# b'\xe5\x90\xb4\xe6\x9e\xab'
# b'\xce\xe2\xb7\xe3'
# 吴枫
# 吴枫
所谓的编码,其实本质就是把str(字符串)类型的数据,利用不同的编码表,转换成bytes(字节)类型的数据。
分隔符还挺常见的,我们在上网的时候,不是会有网址嘛?你经常会看到网址里面有好多的%,它们也是分隔符,替换了Python中的\x。比如像下面这个:
https://www.baidu.com/s?wd=%E5%90%B4%E6%9E%AB
2.文件读写
文件读写,是Python代码调用电脑文件的主要功能,能被用于读取和写入文本记录、音频片段、Excel文档、保存邮件以及任何保存在电脑上的东西。
2.1读文件
文件的地址有两种:相对路径和绝对路径,拖到终端获取的地址是绝对路径。这两种地址,Mac和Windows电脑不太一样。
Mac:
open('/Users/Ted/Desktop/test/word/abc.txt'')
open('word/abc.txt')
Windows:
open('C:\\Users\\Ted\\Desktop\\test\\abc.txt')
#将'\'替换成'\\'
open(r'C:\Users\Ted\Desktop\test\abc.txt')
#在路径前加上字母r
读文件的三步:开——读——关
2.2写文件
写文件很没有创意的——也是三步:打开文件——写入文件——关闭文件。
file1 = open('/Users/Ted/Desktop/test/abc.txt', 'w',encoding='utf-8')
file1.write('写入一些内容\n')
'w'写入模式会给你暴力清空掉文件,然后再给你写入。如果你只想增加东西,而不想完全覆盖掉原文件的话,就要使用'a'模式,表示append,你学过,它是追加的意思。
我们想写入的数据不是文本内容,而是音频和图片的话,该怎么做呢?答案是使用'wb'模式,它的意思是以二进制的方式打开一个文件用于写入。因为图片和音频是以二进制的形式保存的,所以使用wb模式就好了。
OPEN函数练习1
新建一个rantest.txt,里面有几位同学的随堂测验成绩(发现有的同学爱逃课,成就不好哦,也有天才少年,逃课成绩也很棒哦):
赵一 67 65 63
钱二 71 72 75 65 72
孙三 99 97 98 95 90 96
李四 100 99 97 98
现在我们希望统计这些同学的随堂测验总分,并存储在一个新文件中,该怎么办?
**TIPS**需要我们使用split()来把字符串分开,它会按空格把字符串里面的内容分开。
# 定义一个名为file的变量存放读取的文件数据,码率为utf-8
file = open('d:\\rantest.txt','r',encoding='utf-8')
'''
如果直接用read()会导致整个txt文件被打包读取,所以这里用readlines按行读取。
读取后,存储于file_lines变量中
'''
file_lines = file.readlines()
file.close() #文件读取完毕后,记得关闭文件
# 定义列表final_scores,用于后面我们保存需要的数据
final_scores = []
# 用循环的方法,遍历file_lines变量中的每行数据
for i in file_lines:
data = i.split() #定义data变量,存储用split()切分的更细的字符串
sum = 0 #把总成绩设为0
for score in data[1:]: #用到了列表的[A:]写法,意为只遍历A以后的数据
sum = sum + int(score) #切记要把字符串转换为数字
result = data[0]+str(sum) #用result存储学生姓名和成绩
final_scores.append(result) #用append的方式存储学生的最终成绩
print(final_scores)
# 将存储好的学生成绩写入文件中
fintest = open('d:\\fintest.txt','w',encoding='utf-8')
fintest.writelines(final_scores)
fintest.close()
练习2
练习目标
我们会通过今天的作业,复习课堂上学到的知识:编码和解码以及文件读写。
练习要求
对课堂上得到的“winner”文档再行处理一下,让学员的成绩从高到低排列,然后放到新文档“winner_new.txt”。
思路
既然是成绩的排列,就必须知道学生的成绩高低。
1、首先读取winner文档
file1 = open('winner.txt','r',encoding='utf-8')
file_lines = file1.read()
print(file_lines)
file1.close()
得到成绩单:
LEE 102
CHRIS 383
KATE 570
GREEN 275
2、其次创建保存成绩的变量
dict_scores = {}
list_scores = []
final_scores = []
3、最后把几位的成绩取出来,依照由高到底保存到另一个列表中
参考列表的SORT排序即可。
练习3
练习目标
学会直接修改原文件中的数据。
练习要求
语文老师将一些古诗存在txt文档里,一句一行。
最近,他计划抽一些古诗,自己设置一些空来让学生默写。
请你用代码帮老师完成这项工作(只要处理了一个文档,加上循环就能处理无数个文档了)。
思路
老师想的是把诗中需要抽查的句子腾空,那么需要抽查的句子一旦与原文匹配,就可以腾空了。
'''
poem.txt 中存储了原文
《静夜思》
唐朝:李白
床前明月光,
疑是地上霜。
举头望明月,
低头思故乡。
'''
'''
poem1.txt 中用来存储抽查的诗句
《静夜思》
唐朝:李白
床前明月光,
___。
举头望明月,
___。
'''
with open ('d:\\poem.txt','r',encoding='utf-8') as f:
lines = f.readlines() # 这时,lines 的数据存放在内存里。
print (lines) # 将读取到的内容打印出来,发现实际上读到的是带换行符的字符串。
with open('d:\\poem1.txt','w',encoding='utf-8') as new:
for line in lines: # 在内存中,对数据进行处理,然后再写到文档里,覆盖之前的内容。
if line not in ['疑是地上霜。\n','低头思故乡。\n']: # 注意:这里的条件要根据上面打印出的数据写。
new.write(line)
with open ('d:\\poem1.txt','r',encoding='utf-8') as f:
lines = f.readlines() # 这时,lines 的数据存放在内存里。
print(lines) # 将读取到的内容打印出来,发现实际上读到的是带换行符的字符串。