Python中文编码弄到怀疑人生

本文详细介绍了使用Python处理中文字符时可能遇到的问题及解决方法,包括设置正确的编码、处理不同版本Python中的字符串类型差异、数据库连接配置、文件读写编码指定等。特别针对Python 2与Python 3在字符串处理上的区别进行了对比说明。

    新的一个功能因为用到部分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)
<class 'str'>
>>> 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 "<stdin>", line 1, in <module>
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来讲的。

 

转载于:https://my.oschina.net/xiaopei/blog/1620898

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值