Python 中的 str 与 unicode 编码处理

问题

用 Python 处理中文时会经常发现乱码(字符串处理,读写文件,print),多数的做法是调用encode/decode进行调试,并没有明确思考为何出现乱码,所以调试时常出现错误。

理论

若要完全掌握字符编码的处理,必须理解基本知识如 字符编码 | ASCII | Unicode | UTF-8 等。
另外也有一些好的文章可以参考:
字符编码笔记:ASCII,Unicode和UTF-8
淘宝搜索技术博客–中文编码杂谈

示例

Python 中的 str 和 unicode 都是 basestring 的子类
判断是否是字符串的方法:

def is_str(s):
    return isinstance(s, basestring)

str 和 unicode 的转换

str -> decode('the_coding_of_str') -> unicode
unicode -> encode('the_coding_you_want') -> str

s.decode 方法和 u.encode 方法是最常用的,简单说来就是,Python内部表示字符串用 unicode(其实python内部的表示和真实的unicode是有点差别的,对我们几乎透明,可不考虑),和人交互的时候用str对象。
似乎有了 unicode 对象的 encode 方法和 str 的 decode 方法就足够了。奇怪的是 unicode 也有 decode,而 str 也有 encode。
“str.encode(e) is the same as unicode(str).encode(e).
This is useful since code that expects Unicode strings should also work when it is passed ASCII-encoded 8-bit strings.”(from Guido van Rossum)
这段话大概意思是说encode方法本来是被unicode调的,但如果不小心被作为str对象的方法调,并且这个str对象正好是ascii编码的(ascii这一段和unicode是一样的),也应该让他成功。这就是str.encode方法的一个用处 。

str 是字节串,由unicode经过编码(encode)后的字节组成。
1.声明:

s1 = '中文'  #<type 'str'> 
s2 = u'中文' #<type 'unicode'>
s3 = s2.encode('utf-8') #<type 'str'>
s4 = s1.decode('gbk')   #<type 'unicode'>

2.求长度(返回字节数):

>>> u'中文'.encode('utf-8')
‘\xe4\xb8\xad\xe6\x96\x87‘
>>> len(u'中文'.encode('utf-8'))
6

unicode才是真正意义上的字符串,由字符组成。
3.声明

s1 = u'中文' #<type 'unicode'> 
s2 = '中文'.decode('gbk') #<type 'unicode'> 
s3 = unicode('中文', 'utf-8') #<type 'unicode'> 

4.求长度(返回字符数),在逻辑中真正想要用的

>>> u'中文' 
u'\u4e2d\u6587'
>>> len(u'中文')
2

5.判断是否为unicode/str的方法

>>> isinstance(u'中文', unicode) 
True 
>>> isinstance('中文', unicode) 
False
>>> isinstance('中文', str)
True
>>> isinstance(u'中文', str) 
False

总结

使用 Python 处理编码时,输入字符全部转成 unicode, 程序内部全部使用unicode处理,输出再转成目标编码(当然,有例外,处理逻辑中要用到具体编码的情况)。
.py文件默认编码是ASCII,在源代码文件中,如果用到非ASCII字符,需要在文件头部进行编码声明,否则,输入非ASCII会遇到的错误。

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

或者

# coding='utf-8'

若头部声明coding=’utf-8’, a= ‘中文’ 其编码为utf-8
若头部声明coding=’gb2312’, a=’中文’ 其编码为gbk

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值