Python编码问题
Python中乱码问题是一个很头痛的问题。
在Python3中,对中文进行了全面的支持,但在Python2.x中需要进行相关的设置才能使用中文。否则会出现乱码
问题原因:
Python默认采取的ASCII编码,字母、标点和其他字符只使用一个字节来表示
对于中文字符来说,GBK编码下一个中文占两个字节,UTF-8编码下一个中文占三个字节
Python 2.7.11 (v2.7.11:6d1b6a68f775, Dec 5 2015, 20:40:30) [MSC v.1500 64 bit (
AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.getdefaultencoding()
'ascii'
中文计算机系统中的中文编码一般有GBK(兼容GB2312)和UTF-8两种。如果中文编码和ASCII混合使用的话,就会导致解码错误,从而才生乱码。而CMD下默认的编码方式为:GBK,所以会导致乱码!
处理办法:
为了将各种不同的语言包含在统一的字符集中,满足国际间的信息交流,国际上制订了一张通用的字符表即Unicode字符集,包含了世界上所有语言字符,这些字符具有唯一的编码,通过使用Unicode字符集可以满足跨语言的文字处理,避免乱码的产生。
其中UTF-8就是基于Unicode字符集的码点处理后的一种编码。
i) 交互式命令中:一般不会出现乱码,无需做处理
ii) .py脚本文件中:跨字符集必须做设置,否则乱码。
如下面三种:都可以
#coding=utf-8
#coding:utf-8
#_*_ coding:utf-8 _*_
可以查看下http://www.python.org/dev/peps/pep-0263/的解释
粗略的看下:
这个PEP的目的是介绍在一个Python源文件中如何声明编码的语法。随后Python解释器会在解释文件的时候用到这些编码信息。最显著的是源文件中对Unicode的解释,使得在一个能识别Unicode的编辑器中使用如FUT-8编码成为可能
怎么声明:
如果在Python中我们并没有声明别的编码方式,就是以ASCII编码作为标准编码方式的
定义源文件的编码方式的声明应当被放在这个文件的第一行或者是第二行例如:
#coding=<encoding name>
或者(使用流行编辑器中的格式化方式)
#!/usr/bin/python
# _*_ coding: <encoding name> _*_
或者
# vim: set fileencoding=<encoding name> :
不管怎么样,这些在第一行或者第二行的声明都要符合正则表达式
"coding[:=]\s*([-\w.]+)"
所以我们就可以知道为什么使用冒号或者等号都可以了,如果声明的编码python不能识别就会报错
上面的设置是对源文件编码方式的声明
还需要注意的是在保存的时候选择保存为UTF-8格式。
如果是用Notpad文本编辑器打开,选择【另存为】-->UTF-8即可
其他编辑器找到相应编码方式选择UTF-8
编码解码:
以上设置仍然不能保证能输出正常输出中文
不同的编辑器,如VIM,IDLE,Eclipse,CMD使用的输出编码都是不一致的。
所以,在一个地方能正常输出中文,在另外一个地方就未必。所以还必须做编码解码设置!
"string".encode("UTF-8") #编码
"string".decode("UTF-8") #解码
如在python2中,得到某个字符的索引:
#!/usr/bin/env python
#_*_encoding:utf-8_*_
a=[1,2,'中',3,4,5,6,7,5,3,'中',4,9,6,5,2,1,'中',7]
pos=0
for i in range(a.count('中')):
if pos==0:
pos=a.index('中')
else:
pos=a.index('中',pos+1)
print ("中的索引:".decode('utf-8')+str(pos))
输出:
G:\py>python2 test.py
中的索引:2
中的索引:10
中的索引:17
若没有decode则输出为:
G:\py>python2 test2.py
涓殑绱㈠紩:2
涓殑绱㈠紩:10
涓殑绱㈠紩:17
在python3中则不需要decode:
#!/usr/bin/env python
#_*_encoding:utf-8_*_
a=[1,2,'中',3,4,5,6,7,5,3,'中',4,9,6,5,2,1,'中',7]
pos=0
for i in range(a.count('中')):
if pos==0:
pos=a.index('中')
else:
pos=a.index('中',pos+1)
print ("中的索引:"+str(pos))
输出:
G:\py>python34 test2.py
中的索引:2
中的索引:10
中的索引:17