理解Python的编码问题( 二 )


【理解Python的编码问题】s = '中文'b = bytes(s,encoding='utf-8') # s.encode('utf-8')s = str(b,encoding='utf-8') # b.decode('utf-8')上面python2的实验,标准输出编码是gbk,将\xd6\xd0\xce\xc4复制到python3验证编码区别,如下python3的运行情况,可以看到gbk可以正常解码,再进行encode(‘utf-8′)得到bytes字节序列是不是与前面utf-8文本中”中文”的十六进制数据相同 。

理解Python的编码问题

文章插图
 
六、文件路径/文件名/文件读写1.文件路径的困惑存在如下一段代码,遍历目录里面的文件 。
# -*- coding: UTF-8 -*-import osall_files = []for filepath, dirnames, filenames in os.walk(directory): for filename in filenames:tmppath = os.path.join(filepath, filename)all_files.Append(tmppath)print(all_files)python2/python3结果对比 。python3将str视为unicode处理的,所以正常显示 。可以看到python2是以gbk编码来识别目录的 。
理解Python的编码问题

文章插图
 
当前活动代码页是gbk,那python2识别目录是否会受到当前cmd终端编码方式影响?改变当前活动代码页为utf-8后,目录还是以gbk编码识别,encode成utf-8才能正常打印出目录名 。
理解Python的编码问题

文章插图
 
文章开头了解到ANSI编码的特点,是否可以推测python2是以当前系统ANSI编码获取目录名的呢?linux shell验证确实如此 。
理解Python的编码问题

文章插图
 
2.python2的文件名乱码python2运行如下代码,文件名出现了乱码 。
# -*- coding: UTF-8 -*-# python2/python3with open('中文2.txt','w+') as f: f.write("中文")?
理解Python的编码问题

文章插图
 
前面推测python2是以当前系统ANSI编码获取目录名,所以创建文件是否也是这样,由于声明了编码方式是utf-8,而文件名”中文2.txt”字符串是以bytes、utf-8格式存储的,与gbk不一致,所以导致乱码 。尝试将代码改成如下,文件名正常 。
# -*- coding: UTF-8 -*-# python2with open('中文2.txt'.decode('utf-8').encode('gbk'),'w+') as f:#当前编码是utf-8 所以先decode,再encode为系统的gbk编码 f.write("中文")
理解Python的编码问题

文章插图
 
那么找文件读又会是怎样?
# -*- coding: UTF-8 -*-# python2with open('中文2.txt','r') as f: print(f.read().decode('utf-8'))python2执行报错No such file or directory,没有文件或目录 。
理解Python的编码问题

文章插图
 
修改文件名为 ‘中文2.txt’.decode(‘utf-8′).encode(‘gbk’) 后才正常找到了文件,由此可见,python2在识别目录、open创建、读取文件时均以系统ANSI编码识别的,处理中文名称时,需要将目录/文件名字符串先解码,再编码成系统的ANSI编码格式。
3.写入是否正常打开前面python2生成的两个文件,都是utf-8格式,内容中文显示正常!体会到python2的诡异编码了吗?至于这一点,忘了吧…
python3就没那么奇葩了,写入文本后,中文windows系统是ANSI编码,而linux是utf-8编码 。
理解Python的编码问题

文章插图
 

理解Python的编码问题

文章插图
 
python3 open文件操作若不指定编码,则默认以系统ANSI编码写入、读取文本 。建议如果不是以二进制读取和写入,open文件时可指定文本的编码方式 。
f = open("中文1.txt",'a+',encoding='utf-8')4.读取小结不管python2还是python3,解决编码问题的核心都是要解决编码统一 。通过”python2/python3的默认编码”小节,我们认识到python2与python3默认编码的区别,实际上 python文件开头的编码声明声明的是当前脚本内字符串的编码,所以才有了python2打印输出中文时需要先decode(‘utf-8′),再encode(‘gbk’)为cmd终端编码格式,以及中文文件名的编码转换,至于python3,统一了编码,str就是原生unicode,具有普适性,就没有那么多编码转换 。总之,读取文件时,需要明确文件的编码,当前python脚本文件的编码声明,输出的编码 。如果一个utf-8格式文本文件内包含”\xd6\xd0\xce\xc4″、”\u4e2d\u6587″等字符串,读取后又如何处理呢?


推荐阅读