从Python unicodeError看编码
问题:
1. Python脚本实现文本处理
2. 当目录中存在中文时即报错 (unicode error) 'utf8' codec can't decode byte;目录修改为纯英文即通过;
3. python 开头已添加注释,第二行说明编码方式为utf-8(第一行说明该脚本使用python3执行,无需Python xx.py,直接xx.py即可)
#!/usr/bin/python3 # -*- coding:UTF-8 -*-
解决:
初步确认是中文编码问题,标明以utf-8的方式读取脚本,却出现Unicode错误
使用Notepad++编辑文本,在格式选项中选取UTF-8编码(原为ANSI),再次运行问题解决。
但字符编码为二进制,不同的编码规范编码为不同的二进制串,这都知道。但UTF-8和ANSI究竟有什么区别,一直离家差那么一点,今日解决之。
原因分析:
搜索相关文章,大致可以将编码分为2个派系,ASCII和Unicode。
ASCII系
ASCII即为教科书中涉及,包括英文字母大小写及基本符号128个字符与二进制的对应关系(还记得上课时常做的大小写字母转换就是通过 a 97 A 65来算的),1B 8个二进制足以;
非ASCII系,当字符数目超过128个问题即出现,ASCII对照表无法覆盖。于是在此基础上德语/法语/中文等都在扩展,末尾7位沿用(0-127表示相同字符,128-255扩展为其他)。如简体中文 GB2312,2个字节表示一个中文字,理论上可表示256*256= 65536种。GB开头都可认为是国内针对中文字符设置的编码标准,如GBK
注意:以上扩展都是局限于单独某个语言内的。
Unicode
相对的,Unicode是国际组织规定涵盖世界所有语言字符的编码方式,全称Universal Multiple-Octet Coded Character Set。在Unicode中,字符与编码一一对应。
而如何存储这个编码就由UTF(UCS Transformation Format)规范规定,如UTF-8/UTF-16等。UTF-8出现了,它可以看作是Unicode的一种实现。
UTF-8
UTF-8采用变长的编码方式,1-4个字节表示1个字符。
1. 英语系字符采用第一个字节即可,首位为0,与ASCII编码相同。所以,英文的UTF-8编码与ASCII编码相同。
2. 对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。将该字符的Unicode编码从最后一个字节往前填充,不足则补0。
其他,如上截图中的格式仍涉及其他类型编码。
ANSI:具体采用编码与操作系统语言版本有关。针对英文文件采用ASCII,简体中文操作系统使用GBK,在日文操作系统代表 JIS 编码;
USC-2:Unicode的另一种实现,直接用两个字节存储Unicode,超过两个字节的即无法展示,出现乱码。
注. 其中的Little/Big Endian为字节的存储方式,Unicode码是4E25,需要用两个字节存储,存储的时候,4E在前,25在后,就是Big endian方式;25在前,4E在后,就是Little endian方式。
综上,回到遇到的问题。
存储py文件使用了ANSI编码,读取时采用UTF-8,字符读取即出现问题。
特别的,英文字符无报错,是因为ANSI针对英文就是ASCII,UTF-8的第一个字节也是同ASCII,不同编码方式但对英文字符得到相同的结果。
参考文献:感谢大神http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html?20110317170551