Python中的编码问题

花了点时间研究了一下Python中的编码问题,在Python2.*的版本中存在着以下两种字符串的类型:

  • Str类型:这里说的Str类型和我们在C语言里用到的字符串是一个概念,本质就是一个Bytes数组。这个Bytes数组内可以存任意的形式,可以想象UTF-8”格式的字符串、“GBK”格式的字符串、原始格式的字符串等,他们的二进制都不一样,这些二进制都可以放进Str类型里,为我们带来不少困扰,有时候并不知道这个字符串是啥类型的。例如“编码”这两个汉字用UTF-8格式编码对应的二进制就是'\xe7\xbc\x96\xe7\xa0\x81',可以放进这个str类型里
  • Unicode类型: 这里说的Unicode指的是一串Unicode的数字映射(code point), 用于映射某个字符与一个Unicode的对应关系。Unicode就是为了统一各国各地区的编码规则, 重新搞了一套包罗地球上所有文化符号的字符集。Unicode没有编码规则, 只是一套包含全世界符号的字符集。Unicode并不完美,所以之后还出现了UTF-8、UTF-16等,可以认为Unicode和UTF-8对应的二进制是不一样的,UTF-8对应的二进制可以放进Str类型里,Unicode对应的的数字映射可以放进Unicode类型里,例如“编码”这两个汉字用Unicode映射对应的结果是u'\u7f16\u7801'。

   【Python字符串中的Str类型和Unicode类型】

    因此,同样是“编码”两个汉字,分别用Str类型Unicode类型保存时对应的Type完全不一样,以下是他们赋值操作的区别:

   【Str类型和Unicode类型的相互转换】

当然,Python2提供了这两种字符串类型的转换,encode的本意是从Unicode类型转Str类型,decode反之。但是在Python 2.7版本中,还存在str类型.encode(“utf8”)变成另外一个str类型的情况,这让函数的调用更加复杂。在Anaconda Python2.7版本中,中文Str类型.encode(“utf8”)是不支持的,会直接抛Exception。但是在IronPython 2.7版本中,中文Str类型.encode(“utf8”)是支持的,但是会把中文encode成乱码,如下两图所示:

Anaconda Python2.7 不支持中文Str类型.encode(“utf8”)

IronPython2.7支持中文Str类型.encode(“utf8”)

   【json.dumps()函数的ensure_ascii参数】

json.dumps()函数在Anaconda Python2.7和IronPython2.7的行为也是不同的,这个函数有一个重要参数ensure_ascii。Python2.7官方文档对这个参数的解释是: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. Ifensure_ascii is false, some chunks written to fp may be unicode instances. This usually happens because the input contains unicode strings or the encoding parameter is used. 因此,在Anaconda Python2.7中,json.dumps(object, ensure_ascii=True)并不能序列化中文对象;但是在IronPython2.7中json.dumps(object, ensure_ascii=True)在多数情况下是可以序列化中文对象的并且返回一个包含\u序列的中文类型,但在少数情况下,如果原始字符串中存在二进制字符,也会抛错,以下是例子:

           

Anaconda Python2.7 不支持json.dumps(中文object, ensure_ascii=True)

IronPython2.7 多数情况支持json.dumps(中文object, ensure_ascii=True),个别情况不支持json.dumps(中文object, ensure_ascii=True)

例如 TraceId:938e8b9c5289aebba98a81b146982d6a

 

[Python3的行为]

 Python3中str类型直接变成了class str而不是type str,同时encode的结果直接变成了bytes class,避免了胡乱encode的问题。但是如果想要打印一个中文Object仍然需要json.dumps(中文object, ensure_ascii=False)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值