Python 的默认编码是 ASCII(编者注:Python 2.x)html
>>> import sys >>> sys.getdefaultencoding() 'ascii'
因此在 Python 源代码文件中若是不显示地指定编码的话,将出现语法错误。python
#test.py print "你好"
上面是 test.py 脚本,运行 python test.py 就会包以下错误:linux
File “test.py”, line 1 SyntaxError: Non-ASCII character ‘\xe4′ in file test.py on line 1, but no encoding declared; see http://www.python.org/ps/pep-0263.html for details
为了在源代码中支持非 ASCII 字符,必须在源文件的第一行或者第二行显示地指定编码格式:编程
# coding=utf-8
或者windows
#!/usr/bin/python # -*- coding: utf-8 -*-
在 Python 中和字符串相关的数据类型,分别是 str、unicode 两种,他们都是 basestring 的子类,可见 str 与 unicode 是两种不一样类型的字符串对象。编程语言
basestring / \ / \ str unicode
对于同一个汉字”好”,用 str 表示时,它对应的就是 utf-8 编码的 ‘\xe5\xa5\xbd’,而用 unicode 表示时,他对应的符号就是 u’\u597d’,与 u"好" 是等同的。须要补充一点的是,str 类型的字符串具体的编码格式是 UTF-8 仍是 GBK ,仍是其余格式,根据操做系统相关。好比在 Windows 系统中,cmd 命令行中显示的:函数
# windows终端 >>> a = '好' >>> type(a) <type 'str'> >>> a '\xba\xc3'
而在Linux系统的命令行中显示的是:测试
# linux终端 >>> a='好' >>> type(a) <type 'str'> >>> a '\xe5\xa5\xbd' >>> b=u'好' >>> type(b) <type 'unicode'> >>> b u'\u597d'
不管是 Python 3.x、Java 仍是其余编程语言,Unicode 编码都成为语言的默认编码格式,而数据最后保存到介质中的时候,不一样的介质可有用不一样的方式,有些人喜欢用 UTF-8,有些人喜欢用 GBK,这都无所谓,只要平台统一的编码规范,具体怎么实现并不关心。编码
str与unicode的转换 那么在 Pytho n中 str 和 unicode 之间是如何转换的呢?这两种类型的字符串类型之间的转换就是靠这两个方法 decode 和 encode。操作系统
#从str类型转换到unicode s.decode(encoding) =====> <type 'str'> to <type 'unicode'> #从unicode转换到str u.encode(encoding) =====> <type 'unicode'> to <type 'str'> >>> c = b.encode('utf-8') >>> type(c) <type 'str'> >>> c '\xe5\xa5\xbd' >>> d = c.decode('utf-8') >>> type(d) <type 'unicode'> >>> d u'\u597d'
这个 ‘\xe5\xa5\xbd’ 就是 unicode u’好’经过函数 encode 编码获得的 UTF-8 编码的 str 类型的字符串。反之亦然,str 类型的 c 经过函数 decode 解码成 unicode 字符串 d 。
str(s)与unicode(s)
str(s) 和 unicode(s) 是两个工厂方法,分别返回 str 字符串对象和 unicode 字符串对象,str(s) 是 s.encode(‘ascii’) 的简写。实验:
>>> s3 = u"你好" >>> s3 u'\u4f60\u597d' >>> str(s3) Traceback (most recent call last): File "<stdin>", line 1, in <module> UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
上面 s3 是 unicode 类型的字符串,str(s3) 至关因而执行 s3.encode(‘ascii’) ,由于”你好”两个汉字不能用 ascii 码来表示,因此就报错了,指定正确的编码:s3.encode(‘gbk’) 或者 s3.encode(“utf-8”) 就不会出现这个问题了。相似的 unicode 有一样的错误:
>>> s4 = "你好" >>> unicode(s4) Traceback (most recent call last): File "<stdin>", line 1, in <module> UnicodeDecodeError: 'ascii' codec can't decode byte 0xc4 in position 0: ordinal not in range(128) >>>
unicode(s4) 等效于 s4.decode(‘ascii’),所以要正确的转换就要正确指定其编码 s4.decode(‘gbk’) 或者 s4.decode(“utf-8”)。
乱码
全部出现乱码的缘由均可以归结为字符通过不一样编码解码在编码的过程当中使用的编码格式不一致,好比:
# encoding: utf-8 >>> a='好' >>> a '\xe5\xa5\xbd' >>> b=a.decode("utf-8") >>> b u'\u597d' >>> c=b.encode("gbk") >>> c '\xba\xc3' >>> print c ��
utf-8 编码的字符’好’占用3个字节,解码成 Unicode 后,若是再用 gbk 来解码后,只有 2 个字节的长度了,最后出现了乱码的问题,所以防止乱码的最好方式就是始终坚持使用同一种编码格式对字符进行编码和解码操做。
其余技巧
对于如 unicode 形式的字符串(str类型):
s = 'id\u003d215903184\u0026index\u003d0\u0026st\u003d52\u0026sid'
转换成真正的 unicode 须要使用:
s.decode('unicode-escape')
测试:
>>> s = 'id\u003d215903184\u0026index\u003d0\u0026st\u003d52\u0026sid\u003d95000\u0026i' >>> print(type(s)) <type 'str'> >>> s = s.decode('unicode-escape') >>> s u'id=215903184&index=0&st=52&sid=95000&i' >>> print(type(s)) <type 'unicode'> >>>