python对多国语言的处理是支持的很好的,它能够处理如今任意编码的字符,这里深刻的研究一下python对多种不一样语言的处理。
有一点须要清楚的是,当python要作编码转换的时候,会借助于内部的编码,转换过程是这样的:
原有编码 -> 内部编码 -> 目的编码
python的内部是使用unicode来处理的,可是unicode的使用须要考虑的是它的编码格式有两种,一是UCS-2,它一共有65536个码 位,另外一种是UCS-4,它有2147483648g个码位。对于这两种格式,python都是支持的,这个是在编译时经过--enable- unicode=ucs2或--enable-unicode=ucs4来指定的。那么咱们本身默认安装的python有的什么编码怎么来肯定呢?有一个 办法,就是经过sys.maxunicode的值来判断: python
import sys
print sys.maxunicode程序员
若是输出的值为65535,那么就是UCS-2,若是输出是1114111就是UCS-4编码。
咱们要认识到一点:当一个字符串转换为内部编码后,它就不是str类型了!它是unicode类型:shell
a = " 风卷残云 "
print type(a)
b = unicode(a, " gb2312 " )
print type(b)缓存
输出:
<type 'str'>
<type 'unicode'>
这个时候b能够方便的任意转换为其余编码,好比转换为utf-8:函数
c = b.encode( " utf-8 " )
print c编码
c输出的东西看起来是乱码,那就对了,由于是utf-8的字符串。
好了,该说说codecs模块了,它和我上面说的概念是密切相关的。codecs专门用做编码转换,固然,其实经过它的接口是能够扩展到其余关于代码方面的转换的,这个东西这里不涉及。code
codecs模块中重要的函数之一是lookup,它只有一个参数encoding,指的是编码方式的名称,即utf-8或者gb2312等等。对象
lookup函数返回一个包含四个元素的TUPLE,其中t[0]是encoder的函数引用,t[1]是decoder的函数引用,t[2] 是UTF-8编码方式的StreamReader类对象引用,t[3]是UTF-8编码方式的StreamWriter类对象引用相信对Python熟悉的你确定知道接下来该怎么用它们了。接口
codecs模块还提供了方便程序员使用的单独函数,以简化对lookup的调用。它们是:utf-8
若是咱们只是想获取一种utf-8编码的encoder方法,那么只须要这样作:
>>> encoder = codecs.getencoder("utf-8")
上面的代码就是codecs的使用,是最多见的用法。另外还有一个问题就是,若是咱们处理的文件里的字符编码是其余类型的呢?这个读取进行作处理也须要特殊的处理的。codecs也提供了方法.
python读写文件估计你们都用open内置函数,或者file这个工厂函数,这两个的效果基本同样。
打开文件的方式通常为:f=open(file_name,access_mode = 'r',buffering = -1)。file_name就是文件的路径加文件名字,不加路径则文件会存放在python程序的路径下,
access_mode就是操做文件的模式,主要有r,w,rb,wb等,细节网上一大堆,buffering = -1是用于指示访问文件所采用的缓存方式。0表示不缓存;1表示只缓存一行,n表明缓存n行。若是不提供或为负数,则表明使用系统默认的缓存机制。
打开之后就是写和读的操做。可是用open方法打开会有一些问题。open打开文件只能写入str类型,无论字符串是什么编码方式。例如
>>> fr = open('test.txt','a')
>>> line1 = "我爱祖国"
>>> fr.write(line1)
这样是彻底能够的。可是有时候咱们爬虫或者其余方式获得一些数据写入文件时会有编码不统一的问题,因此就通常都统一转换为unicode。此时写入open方式打开的文件就有问题了。例如
>>> line2 = u'我爱祖国'
>>> fr.write(line2)
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
fr.write(line2)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-11: ordinal not in range(128)
>>>
怎么办,咱们能够将上面的line2编码成str类型,可是太麻烦。咱们要把获得的东西先decode为unicode再encode为str。。。
input文件(gbk, utf-8...) ----decode-----> unicode -------encode------> output文件(gbk, utf-8...)
代替这繁琐的操做就是codecs.open,例如
>>> import codecs
>>> fw = codecs.open('test1.txt','a','utf-8')
>>> fw.write(line2)
>>>
不会报错,说明写入成功。这种方法能够指定一个编码打开文件,使用这个方法打开的文件读取返回的将是unicode。写入时,若是参数 是unicode,则使用open()时指定的编码进行编码后写入;若是是str,则先根据源代码文件声明的字符编码,解码成unicode后再进行前述 操做。相对内置的open()来讲,这个方法比较不容易在编码上出现问题。
# -*- encoding: gb2312 -*-
import codecs, sys
# 用codecs提供的open方法来指定打开的文件的语言编码,它会在读取的时候自动转换为内部unicode
bfile = codecs.open( " dddd.txt " , ' r ' , " big5 " )
# bfile = open("dddd.txt", 'r')
ss = bfile.read()
bfile.close()
# 输出,这个时候看到的就是转换后的结果。若是使用语言内建的open函数来打开文件,这里看到的一定是乱码
print ss, type(ss)
总结一下,codecs模块为咱们解决的字符编码的处理提供了lookup方法,它接受一个字符编码名称的参数,并返回指定字符编码对应的 encoder、decoder、StreamReader和StreamWriter的函数对象和类对象的引用。为了简化对lookup方法的调用, codecs还提供了getencoder(encoding)、getdecoder(encoding)、getreader(encoding)和 getwriter(encoding)方法;进一步,简化对特定字符编码的StreamReader、StreamWriter和 StreamReaderWriter的访问,codecs更直接地提供了open方法,经过encoding参数传递字符编码名称,便可得到对 encoder和decoder的双向服务。