关于python内open函数encoding编码问题


在学python的open函数时,我发现在pycharm里新建一个file_name.txt文本文件,输入中文保存,再用open(file_name,'r+')打开,再去读写时出现了一些小问题。利用Notepad和EditPlus进行多轮控制变量测试后,总结如下:

1、当原文件为utf8编码格式,且不包含中文,则对其进行读操作,正常;对其进行写操作(非中文),正常,文件编码格式不变;
当写入中文字符时,文件编码格式变为gbk,此时pycharm中的文件会将你输入的中文显示为16进制数,并会提示你用gbk编码reload文件。
2、当原文件为utf8编码格式,若包含中文,此时对其进行读操作,则可能报错UnicodeDecodeError,也可能不报错。是否报错跟中文内容有关。
写入中文情况与1相同。

如,新建一个文件file4.txt,里面写入"你好"两个汉字,然后去读它:

   结果为:

为什么是 " 浣 犲 ソ " 这三个陌生的玩意呢?查看“你好”的utf8编码16进制表示:

再查看这三个字符的GBK编码16进制表示:

 

 瞬间明白了:open函数用GBK解码了被UTF-8编码的file4文件。前者用两个字节表示一个汉字而后者用三个。

把“你好”换成“中国”再试一次:报错了!

 

因为“中国”的编码前两个字节E4B8根本就没有对应的GBK编码字符。

 

 

 

open的encoding默认为'gbk',可将其改为'utf-8'.

改后也可能会出错!

如:file4输入中英混合的,hello中国

 

再对其进行覆盖写:

 

其utf8 16进制表示为:

68 65 6C 6C 6F     E4 B8 AD    E5 9B BD
覆盖写入"天青色"后:

E5 A4 A9  E9 9D 92  E8 89 B2  9B BD

还剩个9BBD找不到对应的字符,自然就报错了:

 

 

 ----------------------------------------------------------------------华丽的分割线-----------------------------------------------------------------------------

 

补充点编码知识:

Unicode编码其实只是个字符集,把全球的字符用唯一的16进制编号表示出来,这个编号就叫“码位”。最多可表示1114111个,即10FFFF。他没有规定具体怎么存储到计算机硬盘中。而UTF-8就是具体编码的体现,是将码位转化为字节序列的一套编码规则

如:“汉”字的Unicode编码是0x6C49。0x6C49在0x0800-0xFFFF之间, 使用3字节模板: 1110xxxx 10xxxxxx 10xxxxxx。将0x6C49写成二进制是: 0110 1100 0100 1001,用这个二进制数依次代替模板中的x,得到:

11100110 10110001 10001001, 即E6 B1 89。这个就是被存到计算机中的比特流。

 

utf-8的规则:

1. 单字节的字符,字节的第一位设为0,如英文字母,UTF-8码只占用一个字节,和ASCII码完全相同;

2. n个字节的字符(n>1),如中文汉字,第一个字节的前n位设为1,第n+1位设为0,后面字节的前两位都设为10,这n个字节的其余空位填充该字符unicode码,高位用0补足。

U+ 0000 ~ U+ 007F:   0XXXXXXX

U+ 0080 ~ U+ 07FF:   110XXXXX 10XXXXXX

U+ 0800 ~ U+ FFFF:   1110XXXX 10XXXXXX 10XXXXXX

U+10000 ~ U+10FFFF:  11110XXX 10XXXXXX 10XXXXXX 10XXXXXX



 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM