用户想要看的是 u'中文' 而不是 u'\u4e2d\u6587',但是在 Python2 中有时并不能实现。

转译

转义字符是这样一个字符,标志着在一个字符序列中出现在它之后的后续几个字符采取一种替代解释[1]。

>>> ["\u4e2d\u6587"] == ["中文"]
True
>>> '["\u4e2d\u6587"]' == '["中文"]'
True # 取消转义后则不相等
>>> r'["\u4e2d\u6587"]' == r'["中文"]'
False
>>> r'["\u4e2d\u6587"]'
'["\\u4e2d\\u6587"]'
>>> r'["中文"]'
'["中文"]'

由于各种语言的转义机制是不一样的,所以传递 '["\u4e2d\u6587"]' 到浏览器上,浏览器显示的是未转义的 '["\u4e2d\u6587"]'

str()

Python2 str is bytes.

  • unicode encode to bytes
  • bytes decode to unicode
>>> b = u'中文'.encode('utf-8')
>>> type(u'中文')
<type 'unicode'>
>>> type(b)
<type 'str'>
>>> b
'\xe4\xb8\xad\xe6\x96\x87'
>>> b.decode('utf-8') == u'中文'
True

对于 unicode,str() 相当于以默认 encoding 编码:

# -*- coding: utf-8 -*-

import sys
try:
str(u'中文')
except UnicodeEncodeError:
print(u'不能使用 {encoding} 编码非 {encoding} 字符'.format(encoding=sys.getdefaultencoding())) # 不能使用 ascii 编码非 ascii 字符 reload(sys)
sys.setdefaultencoding('UTF8')
print(sys.getdefaultencoding()) # UTF8 print(str(u'中文')) # 中文
print(str(u'中文') == u'中文'.encode(sys.getdefaultencoding())) # True

容器内的 unicode 显示

容器 指一个类、数据结构或者一个抽象数据类型,对应的实例是其他对象的集合。在 Python 中,listdict 都是容器。

在 Python 中,str(container) 对每个 item 调用 repr() 而不是 str() 以获取对应的字符串[2]。而在 Python2 中,repr() 返回一个对象的可打印字符串形式,但是会使用 \x\u 或者 \U 转译字符串中的非 ASCII 字符[3]。

所以我们会看到这样的现象

>>> print({u'\u4e2d\u6587': 1})
{u'\u4e2d\u6587': 1}

而在 Python3 中,repr() 只会转译不可打印的象形符号(glyphs),所以在 Python3 中

>>> print({u'\u4e2d\u6587': 1})
{'中文': 1}

print 做了什么

Python 将 print() 中的参数转换为 bytes str,然后输出到 sys.stdout 上。

目前不清楚如何转换的,只知道不是用 str() 转换:

# -*- coding: utf-8 -*-

print(u'中文') # 中文
print(str(u'中文')) # UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)

处理

显示时将 unicode 以 utf-8 编码为 bytes。

由于 Python2 的默认编码是 ASCII 并且 str() 不支持 encoding 参数,所以不能使用 str()

更改默认编码也不可取[4]。

目前我找到的办法是使用 json.dumps(obj, ensure_ascii=False)

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. If ensure_ascii is false, some chunks written to fp may be unicode instances.

>>> print(json.dumps([u'\u4e2d\u6587', ], ensure_ascii=False))
["中文"]
>>> print(json.dumps([u'\u4e2d\u6587', ], ensure_ascii=True))
["\u4e2d\u6587"]

参考

  1. https://zh.wikipedia.org/zh-hans/转义字符
  2. https://www.python.org/dev/peps/pep-3140/
  3. https://docs.python.org/3/library/functions.html#ascii
  4. https://anonbadger.wordpress.com/2015/06/16/why-sys-setdefaultencoding-will-break-code/

Python2 显示 unicode的更多相关文章

  1. 解决 git 中文路径显示 unicode 代码的问题

    解决 git 中文路径显示 unicode 代码的问题 当被修改的文件中带有中文字符时,中文字符会被转换为 unicode 代码,看不出原来的文件名. 这时,只要配置 :: git config -- ...

  2. 解决Scrapy抓取中文网页保存为json文件时中文不显示而是显示unicode的问题

    注意:此方法跟之前保存成json文件的写法有少许不同之处,注意区分 情境再现: 使用scrapy抓取中文网页,得到的数据类型是unicode,在控制台输出的话也是显示unicode,如下所示 {'au ...

  3. django JsonResponse返回中文时显示unicode编码(\u67e5\u8be2)

    django JsonResponse返回中文时显示unicode编码(\u67e5\u8be2) 关注公众号"轻松学编程"了解更多. 原因 这个unicode编码,是python ...

  4. 【python2/3坑】从gensim的Word2Vec.load()的中文vector模型输出时显示unicode码

    服务器上python2.7 打印出的e[0]对应的是 unicode码 于是分别尝试了用e[0].encode('utf-8')转码 和 e[0].decode('unicode-escape')依然 ...

  5. Python2 下 Unicode 的一个小bug

    关于Python的编码问题已经是老生常谈了,此处主要是介绍一个罕见的问题,也算是Python2的一个bug了(Python3不会有此问题). 在有时候我们去爬取网页或者调用一些第三方库获取文本的时候, ...

  6. Python2 处理 Unicode 字符串的规则

    在 Python2 中处理 Unicode 字符串,需遵循如下规则: 1. 程序中的字符串要加前缀 u 2. 不要用 str(),而应该用 unicode() 作为字符串转换函数.不要使用 chr() ...

  7. python2 中 unicode 和 str 之间的转换及与python3 str 的区别

    在python2中字符串分为unicode 和 str 类型 Str To Unicode 使用decode(), 解码 Unicode To Str 使用encode(), 编码 返回数据给前端时需 ...

  8. python2中将Unicode编码的中文和str相互转换

    在python2x版本中 关于中文汉字转换 1.中文------字符串格式 >>> s = '汉字' >>> type(s) <type 'str'> ...

  9. Eclipse中properties文件,中文只显示Unicode问题(Properties Editor)

    我们常常在properties文件中添加中文注释,而properties文件的中文需用unicode表示, 使用eclipse默认的properties文件编辑器查看显示中文为乱码. 即便修改prop ...

随机推荐

  1. 纹理mag filter不能取GL_XXX_MIPMAP_XXXX

    今天遇到OpenGL error 0x0500错误,定位到 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter); 查看ma ...

  2. 深入Activity

    此刻,你应该静下心来,在阅读中思考.在思考中进步,读完本篇文章的你一定会有不一样的收获,请让我们共同进步! 核心内容 1.Activity数据交换 2.Activity中的任务栈 3.Activity ...

  3. Unity3D刚体不同力的测试(ForceMode,AddForce,RelativeAddForce)

    摘自圣典的一段翻译: ForceAdd a continuous force to the rigidbody, using its mass.添加一个可持续力到刚体,使用它的质量.Accelerat ...

  4. TCP协议的三次握手和四次挥手过程

    TCP是一种面向连接(连接导向)的.可靠的基于字节流的传输层通信协议.TCP将用户数据打包成报文段,它发送后启动一个定时器,另一端收到的数据进行确认.对失序的数据重新排序.丢弃重复数据. 1.TCP/ ...

  5. lantin1

    Latin1是ISO-8859-1的别名,有些环境下写作Latin-1. ISO-8859-1编码是单字节编码,向下兼容ASCII,其编码范围是0x00-0xFF,0x00-0x7F之间完全和ASCI ...

  6. 李洪强和你一起学习前端之(7)定位盒子 css可见性 滑动门案例

    今天是2017年3月23日 1 复习昨天知识 1.1浮动 Float:left | right 特点: ->浮动的元素不占位置(脱标) ->可以将行内元素转化为行内块元素 ->块级元 ...

  7. vs2008、vs2012添加公共头文件

    当我们使用第三方库(opencv.boost)的时候,往往需要把它们的头文件和库文件添加到工程中去,然而如果每次新建工程都添加,那就太笨了,下面介绍方法可以让每个新建的工程都默认添加设置好的头文件和库 ...

  8. vi全文替换命令

    1,$s/str1/str2/g:从第一行到最后一行把str1替换成str2

  9. libubox

    lbubox是openwrt的一个核心库,封装了一系列基础实用功能,主要提供事件循环,二进制格式处理,linux链表实现和一些JSON辅助处理. 它的目的是以动态链接库方式来提供可重用的通用功能,给其 ...

  10. YAML 语法小结

    专门用来写配置文件的语言,非常简洁和强大,远比 JSON 格式方便. 使用缩进表示层级关系 缩进时不允许使用Tab键,只允许使用空格. 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可 # 表示注 ...