基本概念
在Python里有两种类型的字符串类型:字节字符串和Unicode的字符串,一个字节字符串就是一个包含字节列表。 当需要的时候,Python根据电脑默认的locale设置将字节转化成字符。 在Mac OX上默认的编码是UTF-8,但是在别的系统上,大部分是ASCII。
比如创建一个字节字符串:
byteString = "hello world! (in my default locale)"
创建一个Unicode字符串:
unicodeString = u"hello Unicode world!"
将一个字节字符串转成Unicode字符串然后再转回来:
s = "hello byte string"
u = s.decode()
backToBytes = u.encode()
以上代码使用的是系统默认的字符来出来转换的。 然而,依赖系统的区域设置的字符集不是一个好主意,或许你的程序在泰文用户的电脑上就会崩溃。 最好的办法就是为字符指定一个编码:
s = "hello normal string"
u = s.decode("UTF-8" )
backToBytes = u.encode( "UTF-8" )
现在,字节字符串s就被当成一个UTF-8字节列表去创建一个Unicode字符串u, 下一行用UTF-8表示的字符串u转换成字节字符串backToBytes.
如何判断一个对象是字符串
比如这样去判断:
if isinstance( s, str ):
pass
这样是不对的,因为Unicode字符串将不为真.
代替的是使用通用字符串类, basestring
:
if isinstance( s, basestring ):# True for both Unicode and byte strings
pass
单独判断是不是Unicode字符串:
if isinstance( s, unicode ):
pass
读取UTF-8编码的文件
你可以手工转换从文件中读取的字符串,方法很简单:
import codecs
fileObj = codecs.open( "someFile", "r", "UTF-8" )
u = fileObj.read() # Returns a Unicode string from the UTF-8 bytes in the file
codecs模块
可以处理所有的编码转换。
源码的编码声明
Python源代码默认是 ASCII.可以在源文件的第一行或者是第二行作如下声明:
# coding=UTF-8
or (using formats recognized by popular editors):
1 2 | #!/usr/bin/python
# -*- coding: UTF-8 -*-
|
or:
1 2 | #!/usr/bin/python
# vim: set fileencoding=UTF-8 :
|
系统编码
前面说了,Python根据电脑默认的locale设置将字节转化成字符.那如何获得系统的默认编码:
import sys
print sys.getdefaultencoding()
更改系统的默认编码:
import sys
reload(sys)
sys.setdefaultencoding('UTF-8')
为什么要reload sys模块,先看下python的模块加载过程:
# python -v
# installing zipimport hook
import zipimport # builtin
# installed zipimport hook
# /usr/local/lib/python2.6/site.pyc matches /usr/local/lib/python2.6/site.py
import site # precompiled from /usr/local/lib/python2.6/site.pyc
....
Python运行的时候首先加载了site.py,在site.py文件里有这么一段代码:
if hasattr(sys, "setdefaultencoding"):
del sys.setdefaultencoding
在sys加载后,setdefaultencoding方法被删除了,所以我们要通过重新导入sys来设置系统编码.