第十章---文件和编码方式

🌞欢迎来到机器学习的世界 
🌈博客主页:卿云阁 

💌欢迎关注🎉点赞👍收藏⭐️留言📝

🌟本文由卿云阁原创!

🌠本阶段属于练气阶段,希望各位仙友顺利完成突破

📆首发时间:🌹2021年4月5日🌹

✉️希望可以和大家一起完成进阶之路!

🙏作者水平很有限,如果发现错误,请留言轰炸哦!万分感谢!


目录

不同字符编码间的转换

文件操作

打开文件

关闭文件

写文件

读文件

二进制模式操作文件

练习题-全局文本检索替换

不同字符编码间的转换

           windows 系统的默认编码是 GBK, 如果你把⼀段在 windows 系统上⽤ gbk 编码的字符发
送到 mac 电脑 上, mac 默认编码是 utf-8, 那这段文字是乱码显示的。 如何实现在 mac 上正常显示这段 gbk文本呢?

编码与解码

1.把任意编码转换成unicode的过程叫做解码

>>> s="卿云"
>>> s="卿云"#unicode格式
>>> s.encode("utf-8") #将其编码成utf-8
b'\xe5\x8d\xbf\xe4\xba\x91'

2.把unicode转换成的任意编码过程叫做编码

>>> s
'卿云'
>>> s.encode("utf-8").decode("utf-8")#把utf-8编码的字符在转化成unicode
'卿云'
>>> s
'卿云'
>>> s.encode("utf-8") #将其编码成utf-8
b'\xe5\x8d\xbf\xe4\xba\x91

#会变成bytes字节格式,bytes字节类型是用16进制表示的,像\xe5这样两个16进制数是代表一个字节(因为一个16进制数占4位)

字节类型到底是什么

        字节类型其实就是二进制数,只不过为了易于理解,常用16进制数表示。


文件操作

打开文件
f=open(file='C:/Users/Administrator/Desktop/zz.txt',mode='w',encoding='utf-8')  

追加模式
f=open(file='C:/Users/Administrator/Desktop/zz.txt',mode='a')
f.write("zz    202018085\n")
f.close() #保存并关闭
关闭文件
f.close() #保存并关闭
写文件

file.write(s)
f=open(file='C:/Users/Administrator/Desktop/zz.txt',mode='w')  #在文件夹中复制地址时,文件夹中的地址是用 \ 来分隔不同文件夹的,而Python识别地址时只能识别用 / 分隔的地址。
f.write("我叫卿云\n") #写文件
f.write("我喜欢打乒乓球\n") #写文件
f.close() #保存并关闭

file.writelines(s)
file=open('example.txt','w',encoding='utf-8')
# 写入多行内容
lines = ["Line 1\n", "Line 2\n", "Line 3\n"]
file.writelines(lines)

读文件

f=open(file='C:/Users/Administrator/Desktop/zz.txt',mode='r')
print(f.readline())#读一行
print('-----分隔符-----')
data=f.read()
print(data)
f.close() #保存并关闭


结果
卿云  202018081

-----分隔符-----
文竹  202018082
循环文件
f = open(file='C:/Users/qingyun/Desktop/兼职⽩领学⽣空姐模特护⼠联系⽅式.txt',encoding="utf-8",mode='r')
for line in f:
     line = line.split()
     name,addr,height,weight,phone = line
     height = int(height)
     weight = int(weight)
     if height > 170 and weight <= 50: # 只打印身⾼>170 and 体᯿<=50的
         print(line)
f.close()

结果
['⻢纤⽻', '深圳', '173', '50', '13744234523']
['罗梦⽵', '北京', '175', '49', '18623423421']
['叶梓萱', '上海', '171', '49', '18042432324']

二进制模式操作文件

      上面操作的只是文本文件 ,但是如果遇到视频呀、图片呀,你直接打开的话会报错是因为,open() 有个 encoding 参数 , 默认是 None, 是用来告诉解释器,要操作的这个文件 是什么编码。 不填的话,就⽤解释器默认编码,即utf-8
             如果你是⼀个 gbk 编码的文件 ,就必须指定 encoding=gbk
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None,
closefd=True, opener=None)
f = open("gbk_file",encoding="gbk")
for line in f:
 print(line)
     但是像图片、视频,是有自己特殊的编码的,而非什么 unicode\utf-8 这样的文本编码 。 所以要操作这样的文件 ,你用utf-8 什么的去解,自然会报错。
如何处理图⽚、视频⽂件呢?
可以用 2 进制模式打开文件
rb 2 进制只读模式
wb 2 进制创建模式,若⽂件已存在,则覆盖旧文件
ab 2 进制追加模式,新数据会写到文件末尾
这样,你读出来的数据,就是 bytes 字节类型了,当然写进去的也必须是 bytes 格式了
f = open("gbk_file2","wb")
f.write("哈".encode("gbk") ) # 写⼊的⽂本要⽤字节类型

练习题-全局文本检索替换

       写⼀个脚本,允许⽤户按以下⽅式执⾏时,即可以对指定⽂件内容进⾏全局替换,且替换完毕后打印替换了多少处内容
写完后的脚本调用方式:
python your_script.py old_str new_str filename
import sys
old_str=sys.argv[1]
new_str=sys.argv[2]
filename=sys.argv[3]
#1. load into ram
f=open(filename,"r+")
data=f.read()
#2. count and replace
old_str_count=data.count(old_str)
new_data=data.replace(old_str,new_str)
#3. clear old filename
f.seek(0)
f.truncate()
#4.save new data into file
f.write(new_data)
print("成功")
print(f'''成功替换字符'{old_str}' to '{new_str}',共{old_str_count}处...''')

编码方式

二进制运算

        计算机是靠电流驱动的,科学家们是如何做到让电流能理解数字、文字、图片等人类语言的呢? 科学家发现,可以通过控制电压把电流分成高电压、低电压, 高电压可以代表⼀种状态,低电压又可代 表另一状态。这样计算机就可以识别2种状态了。 就像⼀个灯泡,开灯可以代表1,关灯可以代表0,就 是2种状态 。如果多个灯泡的组合,就可以表达更多的值啦。这跟数学⾥的⼀个叫⼆进制的东东很像, ⼆进制只有0和1两个数,想表达更⼤的值 就往左补位,多个0101010就可以表达更⼤的值 啦。 ⼆进制 是逢2进1, 跟我们用的⼗进制逢10进1⼀个原理。 于是科学家们,就⽤2进制做为计算机可识别的最底层语言啦。

 字符编码

      我们自己强行约定了⼀个表,把文字 和数字对应上,这张表就相当于翻译,我们可以拿着⼀个数字来对比对应表找到相应的文字,反之亦然。

ASCII编码

⼀个空格对应的数字是0 翻译成⼆进制就是0(注意字符'0'和整数0是不同的)
⼀个对勾√对应的数字是251 翻译成⼆进制就是11111011

    假如我们要打印两个空格⼀个对勾 写作二进制就应该是 0011111011, 但是问题来了,我们怎么知道从哪儿到哪儿是⼀个字符呢?

       正是由于这些字符串长的长,短的短,写在⼀起让我们难以分清每⼀个字符的起⽌位置,所以聪明的⼈ 类就想出了⼀个解决办法,既然⼀共就这255个字符,那最⻓的也不过是11111111八位,不如我们就把所有的二进制都转换成8位的,不足的用0来替换。 这样⼀来,刚刚的两个空格⼀个对勾就写作000000000000000011111011,读取的时候只要每次读8个 字符就能知道每个字符的二进制值啦。

计算机容量单位

bit 位,计算机中最⼩的表示单位
8bit = 1bytes 字节,最⼩的存储单位,1bytes缩写为1B
1KB=1024B 
1MB=1024KB 
1GB=1024MB # 电影
1TB=1024GB # 移动硬盘
1PB=1024TB 
1EB=1024PB
1ZB=1024EB
1YB=1024ZB
1BB=1024YB

GB2312 & GBK

      英文问题是解决了, 我们中文如何显示呢? 美国佬设计ASSCII码的时候应该是没考虑中国⼈有⼀天也能用上电脑, 所以根本没考虑中文的问题,上世界80年代,电脑进入中国,把砖家们难倒了,ASSCII只能存256个字符,我常用汉字就几千个,怎么玩???勒紧裤腰带还苏联贷款的时候我们都挺过来啦,这点小事难不到我们, 既然美帝的ASCII不支持中文,那我们自己搞张编码表不就⾏了, 于是我们1980年设计出了GB2312编码表,长成下面的样子。⼀共存了6763个汉字。

        这个表格比较大,像上面的⼀块块的文字区域有72个,这导致通过⼀个字节是没办法表示⼀个汉字的 (因为一个字节最多允许256个字符变种,你现在6千多个,只能2个字节啦,2**16=65535个变种)。 有了gb2312,我们就能愉快的写中文啦。

       如何区别连在一起的2个字节是代表2个英文字母,还是⼀个中文汉字呢? 中国⼈如此聪明,2个字节连在⼀起,且每个字节的第1(也就是相当于128的那个2进制位)如果是1,就代表这是个中文,这个首位是128的字节被称为⾼字节。 也就是2个高字节连在⼀起,必然就是⼀个中文。

⼀ 直到现在,我们的windows电脑中文版本的编码就是GBK.

编码战国时代

很多国家都有自己的编码

解决乱码:

1.中国电脑 上装日本 shift_jis

2. 让日本 游戏厂商,用gbk编码

    中国人在搞自己编码的同时,世界上其它非英语国家也得⽤电脑呀,于是都搞出了自己的编码,你可以 想得到的是,全世界有上百种语言,日本把日文编到Shift_JIS里,韩国把韩⽂编到Euc-kr里, 各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码。之前你从玩个日本游戏,往自己电脑上⼀装,就显示乱码了。

这么乱极大了阻碍了不同国家的信息传递,于是联合国出面,发誓要解决这个混乱局⾯。

     因此,Unicode应运而生。Unicode把所有语言都统一到⼀套编码里,这样就不会再有乱码问题了。

 Unicode和UTF-8

              Unicode 2-4字节 已经收录136690个字符,并还在⼀直不断扩张中…Unicode标准也在不断发展,但最常用的是用两个字节表示一个字符(如果要用到非常偏僻的字符,就需要4个字节)。现代操作系统和大多数编程语言都直接支持Unicode

Unicode有2个特点:

1. 支持全球所有语言

2. 可以跟各种语言的编码自由转换,也就是说,即使你gbk编码的文字 ,想转成unicode很容易。 为何unicode可以跟其它语言互相转换呢? 因为有跟所有语言都有对应关系哈,这样做的好处是可以让 那些已经用gbk或其它编码写好的软件容易的转unicode编码 ,利于unicode的推广。 下图就是成unicode跟中文编码的对应关系新的问题又出现了:如果统一  成 Unicode编码,乱码问题从此消失了。但是,如果你写的文本基本上全部是英文的话,⽤Unicode编码⽐ASCII编码需要多⼀倍的存储空间,由于计算机的内存比较大,并且 字符串在内容中表示时也不会特别大,所以内容可以使用unicode来处理,但是存储和网络传输时⼀般 数据都会非常多,那么增加1倍将是无法容忍的!!! 为了解决存储和网络传输的问题,出现了Unicode Transformation Format,学术名UTF,即:对

unicode字符进⾏转换,以便于在存储和⽹络传输时可以节省空间!

UTF-8: 使⽤1、2、3、4个字节表示所有字符;优先使⽤1个字节、⽆法满⾜则使增加⼀个字节,

最多4个字节。英⽂占1个字节、欧洲语系占2个、东亚占3个,其它及特殊字符占4个

UTF-16: 使⽤2、4个字节表示所有字符;优先使⽤2个字节,否则使⽤4个字节表示。

UTF-32: 使⽤4个字节表示所有字符;

总结:UTF 是为unicode编码 设计 的⼀种 在存储 和传输时节省空间的编码⽅案。

如果你要传输的⽂本包含⼤量英⽂字符,⽤UTF-8编码就能节省空间:

UTF-8编码有⼀个额外的好处,就是ASCII编码实际上可以被看成是UTF-8编 码的⼀部分,所以,⼤量只⽀持ASCII编码的历史遗留软件可以在UTF-8编码下继续⼯作。

搞清楚了ASCIIUnicodeUTF-8的关系,我们就可以总结⼀下现在计算机系统通⽤的字符编码⼯作⽅式:

     在计算机内存中,统⼀使⽤Unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为UTF-8编 码。 ⽤记事本编辑的时候,从⽂件读取的UTF-8字符被转换为Unicode字符到内存⾥,编辑完成后,保存的 时候再把Unicode转换为UTF-8保存到⽂件

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卿云阁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值