python 之 字符编码 和 中文显示

关于编码

(首先了解一下ascii、gb2312、gbk、utf-8、unicode的关系 http://www.cnblogs.com/skynet/archive/2011/05/03/2035105.html#_3.4.UTF-8)
a.命令行中编码
>>> import sys 
>>> sys.getdefaultencoding()
'ascii'
>>> a='nihao中国'
>>> a
'nihao\xd6\xd0\xb9\xfa' //‘nihao’是按ascii编码,而中文是按utf-8编码,这么显示是正常的,输出字符实际字节内容,供程序员调试
>>> print a      //print 才是输出给用户看的内容
nihao中国
>>> b='\xd6\xd0\xb9\xfa'
>>> isinstance(b,unicode) //判断是否为unicode编码
False
>>> b1=unicode(b,'gb2312') //转为unicode字符
>>> isinstance(b1,unicode)
True
>>> print b1
中国
>>> b1
u'\u4e2d\u56fd'
>>> b2=b1.encode('utf-8') //转为utf-8编码
>>> isinstance(b2,unicode)
False
>>> print b2
中国
>>> b2
'\xe4\xb8\xad\xe5\x9b\xbd'
 
>>> b='hi'+u'you'  #和Unicode连接,产生Unicode字串 
>>> isinstance(b,unicode)
True
>>> b
u'hiyou'
>>> str(b)  #内置的str()函数把Unicode字串转换成ASCII字串 
'hiyou'
 
 >>> a=["你好","abnd"] 
>>> print a
['\xc4\xe3\xba\xc3', 'abnd']
>>> print a[0]
你好
b.程序中编码 
系统编码如[a]中所示

当python中间处理非ASCII编码时,经常会出现如下错误: UnicodeDecodeError: 'ascii' codec can't decode byte 0x?? in position 1: ordinal not in range(128)

0x??是超出128的数字,python在默认的情况下认为语言的编码是ascii编码,所以无法处理其他编码,需要设置python的默认编码为所需要的编码。
第一种解决方法就是在代码中添加:
  1. import sys
  2. reload(sys)
  3. sys.setdefaultencoding('utf8') #gb2312,gbk
  4. print sys.getdefaultencoding() # 输出当前编码
(对我的系统和程序没有起作用)
 
第二种:
在 python的Lib\site-packages 文件夹下新建一个sitecustomize.py 文件(sitecustomize.py is a special script; Python will try to import it on startup, so any code in it will be run automatically.),输入:
  1. import sys
  2. sys.setdefaultencoding('utf-8')

这样就能够自动的设置编码了。

可以通过第一种方法进行测试。

ps: 为什么要转码?是因为不同的系统、不同的平台使用的编码不一致(最可能导致中文不能正常显示)。那么,如果你在不同的平台进行输入输出操作,首先你要搞清楚 他们的编码,然后进行转码就ok了

相关的搜集
1 http://hi.baidu.com/jiangzubin/item/e3e9072660a690d4ee10f1fd
关于中文字符串和split()方法打印中文
>>> a="一 二 三"
>>> a
'\xd2\xbb \xb6\xfe \xc8\xfd'
>>> print a
一 二 三
>>> a.split()
['\xd2\xbb', '\xb6\xfe', '\xc8\xfd']
>>> a.split()[0]
'\xd2\xbb'
>>> print a.split() //print显示编码,这是问题。或许跟输出方式有关,看下面的解决办法(或解释)
['\xd2\xbb', '\xb6\xfe', '\xc8\xfd']
>>> print a.split()[0]

>>> print "'%s'" % (",".join(b))
'一,二,三'

为什么打印单个元素就可以,而列表就不行?
print一个对象,是输出其“为了给人(最终用户)阅读”而 
设计的输出形式,那么字符串中的转义字符需要转出来,而且 
也不要带标识字符串边界的引号。 
而在命令行下对对象求值,其输出是为了让程序员探求其内在 
特征,所以输出结果是对对象的描述。
现在问题来了,一个list对象,本身就是个数据结构,如果要 
把它显示给最终用户看,而不是用于给程序员调试时,应该如何 
“润色”输出格式呢?这显然应该交给程序员去根据应用的需要 
来做“润色”而不是显示一个用来表示list的方括号,里面却是 
给最终用户看的“润色”过的结果。这种蹩脚输出,对最终用户 
很不知所云,对程序员调试程序又没啥意义。
ps:这段还能理解~print结果针对用户或程序员。就是当我们针对用户用print输出对象时,一般程序员需要对其转义,输出用户期望看到的;
当我们在命令行下输出,默认是给程序员看的,输出其实质内容,未经转义。(准确讲,并没有出错。)
: 我也补充一下。 
:  
: listobject.c 
: PyTypeObject PyList_Type = { 
:         PyObject_HEAD_INIT(&PyType_Type) 
:         0, 
:         "list", 
:         sizeof(PyListObject), 
:         ... 
:         (reprfunc)list_repr,                    /* tp_repr */ 
:         0,                                      /* tp_str */ 
:         ... 
: }; 
:  
: list.__str__没有实现,所以list.__str__ == object.__str__ 
: 而运行时的object.__str__会去调用list.__repr__(object.c), 而list.__repr__会对自己的元素调用object.__repr__,所以当元素为str类型的话,就是str.__repr__了 
ps:程序没看懂,解说算看懂了吧。

2 还是关于此错误
UnicodeDecodeError: 'ascii' codec can't decode byte 0x?? in position 1: ordinal not in range(128)
参考  http://blog.chinaunix.net/uid-10597892-id-2946918.html
特别有用的理解:
字符串在Python内部的表示是unicode编码,因此,在做编码转换时,通常需要以unicode作为中间编码,即先将其他编码的字符串解码(decode)成unicode,再从unicode编码(encode)成另一种编码。
decode的作用是将其他编码的字符串转换成unicode编码,如str1.decode('gb2312'),表示将gb2312编码的字符串str1转换成unicode编码。
encode的作用是将unicode编码转换成其他编码的字符串,如str2.encode('gb2312'),表示将unicode编码的字符串str2转换成gb2312编码。

3 http://www.360doc.com/content/11/0213/01/2563193_92593666.shtml 
On my win7(Python 2.7.3)
>>> s=u"中文"  //明显没事找事,unicode编码有必要拉上中文么,中文为uft-8编码,又来个unicode声明,乱了吧
>>> print s   //看,乱码了吧
ÖÐÎÄ
>>> import sys
>>> sys.getdefaultencoding()
'utf-8'
>>> print s.encode('utf-8')   //本来编码就混乱了,这里encode也会晕的吧,乱码
脰脨脦脛
>>> s
u'\xd6\xd0\xce\xc4'             //看,unicode + utf-8
>>> print '\xd6\xd0\xce\xc4'    //纯utf-8编码
中文
>>> s='中文'
>>> print s
中文
>>> s
'\xd6\xd0\xce\xc4'

4 其他
http://blog.iamzsx.me/show.html?id=81001
http://hi.baidu.com/l4yn3/item/136bd2157b9ed2456926bb83
http://www.zhidaow.com/?p=310
http://www.zhidaow.com/?p=267
http://baike.baidu.com/view/664966.htm
http://www.oschina.net/code/snippet_70229_2348
原文地址:https://www.cnblogs.com/20120810bubu/p/3036132.html