Python 2 中对列表和字典中的中文进行输出的时候,都无法原样打印
>>> l=[‘你好‘,‘版块‘,‘博客‘,‘字典‘]>>>print l
[‘\xc4\xe3\xba\xc3‘, ‘\xb0\xe6\xbf\xe9‘, ‘\xb2\xa9\xbf\xcd‘, ‘\xd7\xd6\xb5\xe4‘]>>>
当前是运行在 win10 , python 2.7
>>> importsys,locale>>>sys.getdefaultencoding()‘ascii‘
>>>locale.getdefaultlocale()
(‘zh_CN‘, ‘cp936‘)>>>sys.stdin.encoding‘cp936‘
>>>sys.stdout.encoding‘cp936‘
相对的 python3的环境如下:
>>> importsys,locale>>>sys.getdefaultencoding()‘utf-8‘
>>>locale.getdefaultlocale()
(‘zh_CN‘, ‘cp936‘)>>>sys.stdin.encoding‘utf-8‘
>>>sys.stdout.encoding‘utf-8
由此对比可得,python3的标准输出默认utf-8所以中文输出没问题,但python2.7的是cp936所以输出不是我们希望的结果。
这里列举几种解决方法:
str类型的中文
1、逐个打印
直接print容器中的元素
>>> l=[‘你好‘,‘版块‘,‘博客‘,‘字典‘]>>> for k inl:printk
你好
版块
博客
字典
>>> for k, v in {‘name‘: ‘张三‘}.items():
print k,v
name 张三
对于简单的容器对象,还是很方便的,但是对于嵌套的容器对象,就麻烦了
2、json dumps
这个方法在网上推荐的较多
>>> data = {‘严‘: 1, 2: [‘如‘], 3:‘玉‘}>>> importjson>>> dumped_data = json.dumps(data, encoding = ‘gbk‘, ensure_ascii=False)>>> printdumped_data
{"2": ["如"], "3": "玉", "严": 1}
可以看到,虽然打印出了中文,但是2 3都被加上了引号,感觉怪怪的
需要注意的是上面的两个参数(encoing ensure_ascii), 这两个参数都有默认参数(encoding = ‘utf-8‘, ensure_ascii=True),跟我们这里使用的都不一样。
ensure_ascii参数也很关键
>>> dumped_data = json.dumps(data, encoding = ‘gbk‘)
>>> print dumped_data
{"2": ["\u5982"], "3": "\u7389", "\u4e25": 1}
python document是有描述的;
If ensure_ascii is True (the default), all non-ASCII characters in the output are escaped with \uXXXX sequences, and the result is a str instance consisting of ASCII characters only.
3、repr string_escape
>>> decoded_data = repr(data).decode(‘string_escape‘)>>> printdecoded_data
{2: [‘如‘], 3: ‘玉‘, ‘严‘: 1}
既然repr的输出是十六进制的str,那么就可以使用string_escape进行转换,具体也可以参见上文
4、PEP3140
虽然PEP3140被reject了,但我们还是可以利用其思想吧,那就是强制调用str.__str__而不是str.__repr__
classForceStr(str):def __repr__(self):return super(ForceStr, self).__str__()defswitch_container( data ):
ret=Noneifisinstance(data, str):
ret=ForceStr(data)elif isinstance(data, list) orisinstance(data, tuple):
ret= [switch_container(var) for var indata]elifisinstance(data, dict):
ret= dict((switch_container(k), switch_container(v)) for k, v indata.iteritems())else:
ret=datareturn ret
>>> switched_data =switch_container(data)>>> printswitched_data
{2: [如], 3: 玉, 严: 1}>>>switched_data
{2: [如], 3: 玉, 严: 1}
unicode类型的中文
基本姿势于上一章节是一样的,下面直接给出答案
同上第二种姿势
>>> udata = {u‘严‘: 1, 2: [u‘如‘], 3:u‘玉‘}
>>> print json.dumps(udata, encoding = ‘gbk‘, ensure_ascii=False)
{"2": ["如"], "3": "玉", "严": 1}
同上第三种姿势
>>> print repr(udata).decode(‘unicode_escape‘)
{2: [u‘如‘], 3: u‘玉‘, u‘严‘: 1}
>>>
同上第四种姿势
1 def switch_container( data ):
2 ret = None
3 if isinstance(data, unicode):
4 ret = ForceStr(data.encode(sys.stdout.encoding))
5 elif isinstance(data, list) or isinstance(data, tuple):
6 ret = [switch_container(var) for var in data]
7 elif isinstance(data, dict):
8 ret = dict((switch_container(k), switch_container(v)) for k, v in data.iteritems())
9 else:
10 ret = data
11 return ret
>>>
>>> print switch_container(udata)
{2: [如], 3: 玉, 严: 1}
当str与unicode中文并存时
同上第二种姿势
>>> data[4] = u‘啊‘
>>> print json.dumps(data, encoding = ‘gbk‘, ensure_ascii=False)
{"2": ["如"], "3": "玉", "4": "啊", "严": 1}
同上第三种姿势
>>> print repr(data).decode(‘string_escape‘)
{2: [‘如‘], 3: ‘玉‘, 4: u‘\u554a‘, ‘严‘: 1}
呃,unicode中文打印不出来
>>> print repr(data).decode(‘unicode_escape‘)
Traceback (most recent call last):
File "", line 1, in
UnicodeEncodeError: ‘gbk‘ codec can‘t encode character u‘\xc8‘ in position 6: illegal multibyte sequence
>>>
擦,也许有正确的姿势,不过我没有试出来
同上第四种姿势
1 def switch_container( data ):
2 ret = None
3 if isinstance(data, str):
4 ret = ForceStr(data)
5 elif isinstance(data, unicode):
6 ret = ForceStr(data.encode(sys.stdout.encoding))
7 elif isinstance(data, list) or isinstance(data, tuple):
8 ret = [switch_container(var) for var in data]
9 elif isinstance(data, dict):
10 ret = dict((switch_container(k), switch_container(v)) for k, v in data.iteritems())
11 else:
12 ret = data
13 return ret
>>> print switch_container(data)
{2: [如], 3: 玉, 4: 啊, 严: 1}
总结
json.dumps版本还算可以,能够处理str中文,unicode中文, str与unicode中文并存三种情况,不过显示结果与真实有点差异
string_escape(unicode_escape)只使用只有str(unicode)中文的情况,使用较为受限
自己实现的switch_container版本,能够友好支持str中文,unicode中文,str与unicode中文并存三种情况
str与unicode并存真是一件蛋疼的事情!