Python中文编码弄到怀疑人生

2018-02-11 14:09:20来源:oschina作者:叫我哀木涕人点击

分享

新的一个功能因为用到部分pandas的功能,所以python还是很好的一个用的语言。但是在处理中文,真是让人对这个编码有学习了一遍。


简单的总结几点,回忆一下排查过程。大家在碰到这个问题的时候也能够提供简单参考。


1,python语言本身开头添加# -*- coding: utf-8 -*-。这个是干啥用的,按照PEP 0263的描述: -- Defining Python Source Code Encodings,避免python代码里面有中文而报错


2,如果python是2的版本,需要在python脚本import后添加sys.setdefaultencoding('utf8')的语言描述,因为2的默认编码是ascii,避免隐式转换。


3,对于有数据库读取数据的,比如mysql数据库编码是utf8,要在连接参数加上“charset=utf8”,显示指明编码。


4,读出的中文编码在终端打印的时候可能是乱码,需要看终端显示的编码。


5,笔者用的是python3,还是少了很多麻烦,不用去设置sys.setdefaultcharset,也不必担心当前变量是不是Unicode。因为python3默认就是字符串,也可以理解为就是Unicode。这个时候想要对其编码只能用encode,然后返回的是bytes类型。下面是测试例子、


python2.7的情况


>>> s = "你好"
>>> s
'/xe4/xbd/xa0/xe5/xa5/xbd'
>>> su = u"你好"
>>> su
u'/u4f60/u597d'
>>> print su
你好
>>> print s
你好
>>> s.decode('utf8')
u'/u4f60/u597d'
>>> print s.decode('utf8')
你好

python3.6的情况


>>> s = '你好'
>>> s
'你好'
>>> type(s)

>>> s.encode('utf8')
b'/xe4/xbd/xa0/xe5/xa5/xbd'
>>> s.encode('gbk')
b'/xc4/xe3/xba/xc3'
>>> s.decode('utf8')
Traceback (most recent call last):
File "", line 1, in
AttributeError: 'str' object has no attribute 'decode'
>>>
>>> print(s)
你好
>>> su8 = s.encode('utf8')
>>> su8
b'/xe4/xbd/xa0/xe5/xa5/xbd'
>>> print(su8)
b'/xe4/xbd/xa0/xe5/xa5/xbd'
>>> print(su8.decode('utf8'))
你好

大家可以仔细对比下。python2稍微混些,因为字符串也是能够decode。


其实python语言对字符串的设计也是让人容易迷惑。python里面理解Unicode是文本字符串,而str是字节字符串。python语言不过是默认屏蔽掉这点让我们无感的使用。但是对于java或者其他语言是不把字节当字符串来处理的。


所以这点的建议是不要对Unicode使用str方法,也不要对str变量使用Unicode,谨记。特别是在2.7的版本。在处理字符串的时候使用正确解码,当应用从外部读取数据时,应将其视为字节串str类型,接着调用.decode() 将其解释成文本。同样在将文本发送到外部时,总是对文本调用.encode()。

6,在读入或者写入的时候,也要指明编码。


笔者在向文本写数据的时候代码如下:


username = row[0]
fd = open('/tmp/t.csv', 'w')
fd.write(username)
fd.close()

在pandas读取的时候,报错UnicodeDecodeError: 'utf-8' codec can't decode byte 0xca in position 0: invalid continuation byte。报这个错误是因为提供给pandas的文本不是utf8编码。把文本下载到windows系统看了看,其文本编码为ANSI。文本中文也能正确展示,但是提示需要选择编码。之前有见过这个编码但是不了解是什么东西,笔者查了下其实就是一种本地化的ASCII编码的扩展集。就是会根据系统来选择对于的编码来展示。这个时候想起写文本的时候,是不是有第三个参数。一查果然有加上'utf-8'就可以正常执行了。


最后建议还是早点升级python3的版本,幸福一点。理解编码原理,Unicode是一种编码规范,而UTF-8是一种实现方案。encode和decode的对于中间码Unicode来讲的。


最新文章

123

最新摄影

闪念基因

微信扫一扫

第七城市微信公众平台