python2中打印列表与字典内的中文字符
在开发过程中,我们经常需要打印一些变量的值,便于调试。这个时候就会发现如果在列表与字典这些容器中,如果包含中文字符,不管是str类型,还是unicode类型,都打印不出来。如下:
>>> print {'name': '张三'}
{'name': '\xe5\xbc\xa0\xe4\xb8\x89'}
>>> print {'name': u'张三'}
{'name': u'\u5f20\u4e09'}
当然,我们很难自行脑补这些十六进制的意思,每次转移一下也很麻烦,有没有办法一劳永逸呢。
>>> import sys,locale
>>> sys.getdefaultencoding()
'ascii'
>>> locale.getdefaultlocale()
('zh_CN', 'UTF-8')
>>> sys.stdin.encoding
'UTF-8'
>>> sys.stdout.encoding
'UTF-8'
首先让我们分析一下为什么无法打印包含中文的容器(dict list tuple)
>>> data = {'严': 1, 2: ['如'], 3:'玉'}
>>> data
{'\xe4\xb8\xa5': 1, 3: '\xe7\x8e\x89', 2: ['\xe5\xa6\x82']}
>>> print data
{'\xe4\xb8\xa5': 1, 3: '\xe7\x8e\x89', 2: ['\xe5\xa6\x82']}
>>> print data[3]
玉
上面data在key value中包含中文,而且也有嵌套的list,后文都使用这个data
可以看到不管是直接输出data(调用dict.__repr__),还是print data(调用dict.__str__),都无法输出中文,而是像str.__repr__的结果。即调用容器的__str__时,事实上调用的是容器元素的__repr__方法,这个很好验证:
>>> class OBJ(object):
... def __str__(self):
... return 'OBJ str'
... def __repr__(self):
... return 'OBJ repr'
...
>>> lst = [OBJ()]
>>> print lst
[OBJ repr]
OBJ这个自定义的类,__str__ __repr__的方法实现不一样,当作为容器(list)的元素时,明显调用的是OBJ.__repr__
在stackoverflow上的一个问题print-a-list-that-contains-chinese-characters-in-python给出了答案
When you print foo, what gets printed out is str(foo).
However, if foo is a list, str(foo) uses repr(bar) for each element bar, not str(bar).
当然,这个问题早就被人发现了,在PEP3140 str(container) should call str(item), not repr(item) ,在这个提议中,就建议在打印容器的时候,使用__str__而不是__repr__。但是被Guido(Python之父)无情的拒绝了,原因是:
Guido said this would cause too much disturbance too close to beta
虽然提议被reject了,但是需求还是照样存在的啊,于是有了各种解决办法
第一种方法:逐个打印
直接print容器中的元素
>>> lst = ['张三', '李四']
>>> print '[' + ', '.join(["asdf", "中文"]) + ']'
[asdf, 中文]
>>> for k, v in {'name': '张三'}.items():
... print k, v
...
name 张三
对于简单的容器对象,还是很方便的,但是对于嵌套的容器对象,比如上面data的例子,就很麻烦了
第二种方法: json dumps
这个方法在网上推荐得较多
>>> import json
>>> dumped_data = json.dumps(data, encoding = 'UTF-8', ensure_ascii=False)
>>> print dumped_data
{"严": 1, "3": "玉", "2": ["如"]}
可以看到,虽然打印出了中文,但是2 3都被加上了引号,感觉怪怪的
需要注意的是上面的两个参数(encoing ensure_ascii), 这两个参数都有默认参数(encoding = 'utf-8', ensure_ascii=True)
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.
第三种方法: repr string_escape
>>> decoded_data = repr(data).decode('string_escape')
>>> print decoded_data
{'严': 1, 3: '玉', 2: ['如']}
既然repr的输出是十六进制的str,那么就可以使用string_escape进行转换,具体也可以参见上文
第四种方法:PEP3140
虽然PEP3140被reject了,但我们还是可以利用其思想吧,那就是强制调用str.__str__而不是str.__repr__
class ForceStr(str):
def __repr__(self):
return super(ForceStr, self).__str__()
def switch_container( data ):
ret = None
if isinstance(data, str):
ret = ForceStr(data)
elif isinstance(data, list) or isinstance(data, tuple):
ret = [switch_container(var) for var in data]
elif isinstance(data, dict):
ret = dict((switch_container(k), switch_container(v)) for k, v in data.iteritems())
else:
ret = data
return ret
>>> switched_data = switch_container(data)
>>> print switched_data
{2: [如], 3: 玉, 严: 1}
>>> switched_data
{2: [如], 3: 玉, 严: 1}
ForceStr继承自str,然后ForceStr.__repr__调用str.__str__。然后递归将容器里面的str类型的元素替换成ForceStr。可以看到,能够顺序打印出中文,格式也没有问题
python2中打印列表与字典内的中文字符的更多相关文章
- Day 08 可变与不可变对象/列表与字典内置方法
目录 可变对象与不可变对象 可变对象 不可变对象 列表的内置方法 字典内置方法 可变对象与不可变对象 可变对象 对象指向的内存中的值会改变,当更改这个变量的时候,还是指向原来内存中的值,并且在原来的内 ...
- python中的列表和字典
列表和字典的区别: 列表是有序排列的一些物件,而字典是将一些物件(键)对应到另外一些物件(值)的数据结构; 应用场景: 字典 各种需要通过某个值去查看另一个值的场合,也就是一个虚拟的“查询表”,实现方 ...
- python中的列表和字典(一)
一. 列表 1. 列表的定义 [] 2. 列表特征:有序列表,可以包含任意内容,可以重复 3. 列表的赋值(顺序赋值):listA = [A, B, C] 4. 列表的取值:list[index] ...
- Python2中的列表推导式存在变量泄漏问题,在Python3中不存在
列表推导式(list comprehension) Python2: >>> x = 'my homie' >>> dummy = [x for x in 'ABC ...
- JAVA- JSP中解决无法在Cookie当中保存中文字符的问题
因为cookie的值是ASCII字符,不能直接把自定义cookie的值直接赋值为中文,但是要实现这个功能,还是有方法的. 1.java中已经给我们提供了方法,此时只需要导入该包就行 <%@ pa ...
- Python从文件中读取字符串,用正则表达式匹配中文字符的问题
2013-07-27 21:01:37| 在Windows下,用Python从.txt文件中读取字符串,并用正则表达式匹配中文,在网上看了方法,用的时候发现中文没有被匹配. ...
- Python中打印列表的序号和内容
==>the start 最近作业里要用到遍历打印出列表中的序号和内容,我刚开始用了个很笨的方法来写,后来老师说可以使用enumerate()函数,所以我就特意研究了下. 先看我之前用的笨方法: ...
- 关于在Python2中使用列表推导式会遇到的问题
摘自<流畅的Python>第二部分第二章2.2 Python 2.x 中,在列表推导中 for 关键词之后的赋值操作可能会影响列表推导上下文中的同名变量.像下面这个 Python 2.7 ...
- python中的列表和字典(二)
三. 字典以及相关使用 1. 字典的定义 dict{} 2. 字典特征:字典是无序的,key-value键值对形式,key值不重复 3. 字典的赋值:dictA = {keyA: valueA, ke ...
随机推荐
- xBIM 基础11 WeXplorer 常用事件
系列目录 [已更新最新开发文章,点击查看详细] 本篇将介绍查看器在不同场合触发的事件.所有这些都记录在xViewer中. 如果您从Web服务器运行本教程,可以在此处查看完整的实例.并且确保您的 ...
- Linux命令详解./configure,make,make install的作用
这些都是典型的使用GNU的AUTOCONF和AUTOMAKE产生的程序的安装步骤. ./configure是用来检测你的安装平台的目标特征的.比如它会检测你是不是有CC或GCC,并不是需要CC或GCC ...
- 你不知道的JavaScript(五)内置对象模版
尽管JavaScript中有对象的概念,但一般我们并不说JavaScript是面向对象的编程语言,因为它不具备面向对象的一些最基本特征. 在c++/Java等这些面向对象的编程语言中,我们要定义一个对 ...
- JavaScript学习——JS事件总结
回顾之前已经使用过的事件 (onsubmit.onclick.onload.onfocus.onblur.onmouseover.onmouseout) onfocus/onblur:聚焦离焦事件,用 ...
- eclipse oxygen离线安装activiti
我用的最新版本的eclipse oxygen,结果通过help-->install new software-->add 一直报找不到,后来网上查找的离线安装,终于成功了,在这里和大家分享 ...
- XShell与虚拟机连接的IP问题
这几天在Xshell连接虚拟机这个问题上头疼了好长时间,原因是我在虚拟机内的eth0网卡没有分配IP地址,从而导致无法连接XShell,今天解决了这个问题,做一下记录. 首先我使用的是微软的Hyper ...
- array_key_exists()
array_key_exists()方法用于检查键名是否存在数组中. <?php $a=array("name"=>"XC90","tex ...
- JS脚本代替人工输入
最近接到了个任务,对某个网页上的1000个item填写相同的text,text的内容相同. 这显然是机械动作呀,干脆写个工具,用脚本代替人工操作. 浏览器按F12,找到console,输入写好的脚本, ...
- 紫书 习题8-4 UVa 11491 (贪心)
题意:给你一个数, 要求删去一些数字, 使得剩下的数字最大. 这道题用贪心解决. 大家想一想, 两个数比较大小, 肯定先比较第一位的数,然后依次比较第二位,以此类推. 既然我们要保证最后的数字最大, ...
- Linux下库文件的设置 (/usr/bin/ld: cannot find -lxxx 的解决办法)
在软件编译过程中,经常会碰到类似这样的编译错误: /usr/bin/ld: cannot find -lhdf5 这表示找不到库文件 libhdf5.so,若是其它库文件,则是 cannot find ...