codesc官方地址:https://docs.python.org/2/library/codecs.html
相关帮助:http://www.cnblogs.com/huxi/archive/2010/12/05/1897271.html
#python标准库(英文地址:)http://www.ask3.cn/ebook/docspy3zh/library/index.html
unicode入门:
cpython2.xz支持2种类型字符串处理文本数据,老式的str实例使用单个8位字节表示字符串字符(ascii码),与之不同的unicode串在内部作为一个unicode码点(codepoint)序列来管理,码点值分别保存为2个或者4个字节序列,这取决于编译python时指定的选项,unicode和str都派生一个共同基类,并支持类似的api.
输入unicode串时,会使用某种标准机制编码,使得以后可以将这个字节序列重构为同样的文本串,编码值的字节不一定与码点值完全相同,编码只是定义了在2个值集之间转换的一种方式,读取unocide数据时还需要知道编码,这样才能接到字节转换为unicode类使用内部表示!
西方语言最常用的编码是utf-8 utf-16这2种编码 分别使用单字节和2字节值序列表示各个码点,对于其他语言,由于大多数字符由走过个字节码点表示,所以使用其他编码来存储可能更为高效
#注意:unicode论坛:http://www.unicode.org/ 或者请看<the python unicode howto>书籍信息
#编码
要了解编码,最好的方法就是采用不同方式对相同串进行编码,并查看所生成字节序列的区别
例子:
import binasciidef to_hex(t,nbytpes): item=nbytpes*2 hex1=binascii.hexlify(t) return ' '.join(hex1[s:s+item]for s in xrange(0,len(hex1),item))print to_hex('abcdef',1)print to_hex('abcdef',2)#这个函数使用binascii得到输入字节码的十六进制,在返回这个值之前每隔nbytpes字节就插入一个空格 #第一个编码例子首先使用uncidoe类的原始表示打印文本pi:π,π(3.14)字符替换为unicode码点的表达式\u03c0,接下来使用utf-8 utf-16,得到十六进制text=u'pi:,π'print 'raw :',repr(text)print 'utf-8:{0} and utf-16{1}'.format(to_hex(text.encode('utf-8'),1),to_hex(text.encode('utf-16'),2))#对于一个unicode串编码 的结果是一个str对象 #给定一个编码字节序列(作为一个str实例),decode()方法会将其转换为码点,并作为一个unicode实例返回转换后序列en=text.encode('utf-8')de=en.decode('utf-8')print 'original:',repr(text)print 'en:',to_hex(en,1),type(en)print 'de:',repr(de),type(de)#注意:解释器启动过程中(即加载site时)会设置默认编码,关于默认编码设置的描述,可以参考sys部分(或者文档) #处理文件
"""处理i/o操作时,编码和解码字符串尤其重要,否认是写入一个文件,一个套接字还是另外一个流,数据都必须使用适当的编码,一般来讲,所有文本数据在读取时都需要从其字节表示解码,写时则需要从内部值 编码为一种特定表示,一种程序可以地编码和解码数据,但是取决于手忙脚乱的编码,是确定是否已读取足够的字节以便充分解码数据,这一点可能并不容易。codes提供了一些类来管理数据的编码和解码,所以应用不需要做这个工作codes提供了最简单的接口可以来替代open()内置函数,新版本函数和内置函数做法相信,不过增加了2个参数来指定编码和所需的错误处理技术"""import sys,codecsen=sys.argv[0]filename=en+'.txt'print 'writing to:',filenamewith codecs.open(filename,mode='wt',encoding=en)as f: f.write(u'pi:\u03c0')n={''utf-8:1,'utf-16':2,'utf-32':4}.get(en,1)print 'file contents:'with open(filename,mode='rt')as f: print to_hex(f.read(),n)#这个例子首先从一个unicode串开始(包括pai的码点),并使用命令行指定指定的编码将文件保存到一个文件中使用open()读取数据很简单,但提前是需要知道它的编码,才能正确的建议解码器,尽管有些数据格式(如;xml)会指定编码作为文件一部分,但是通常都要由应用特定来管理,codecs只是取一个编码参数,并假设这个编码是正确的.
en=sys.argv[0]filename=en+'.txt'print 'writing to:',filename
with codecs.open(filename,mode='wt',encoding=en)as f:
print repr(f.read())
字节顺序
多字节编码utf - 16和utf - 32等问题 不同的计算机系统之间传输数据,通过 直接复制文件或网络通信。 不同的 系统使用不同的排序的高和低字节顺序。 这 数据的特点,被称为它的字节顺序,取决于 等因素的硬件架构和选择 操作系统和应用程序开发人员。 并不总是有一种方法 提前知道使用什么字节顺序对于一个给定的数据集,所以 包括一个多字节编码的字节顺序标记(BOM)的 前几个字节的编码输出。 例如,定义utf - 16 的方式0 xfffe和0 xfeff无效字符,和可以 被用来表示字节顺序。编解码器定义常量 使用的字节顺序标记utf - 16和utf - 32。
for name in [ 'BOM', 'BOM_BE', 'BOM_LE', 'BOM_UTF8', 'BOM_UTF16', 'BOM_UTF16_BE', 'BOM_UTF16_LE', 'BOM_UTF32', 'BOM_UTF32_BE', 'BOM_UTF32_LE', ]: print '{:12} : {}'.format(name, to_hex(getattr(codecs, name), 2)) 取决于当前系统固有字节序,bom,bom_utf16,bom_utf-32会自动设置为适合的大端(big-endian)或者小端(little-endian)值#信息库:
BOM : fffe BOM_BE : feff BOM_LE : fffe BOM_UTF8 : efbb bf BOM_UTF16 : fffe BOM_UTF16_BE : feff BOM_UTF16_LE : fffe BOM_UTF32 : fffe 0000 BOM_UTF32_BE : 0000 feff BOM_UTF32_LE : fffe 0000 可以由codecs中解码器自动检测和处理字节序,不过编码时也可以地指定字节序.#下面这个a.py文件,代码如下:
if codecs.BOM_UTF16 == codecs.BOM_UTF16_BE: bom = codecs.BOM_UTF16_LE encoding = 'utf_16_le' else: bom = codecs.BOM_UTF16_BE encoding = 'utf_16_be' print 'Native order :', to_hex(codecs.BOM_UTF16, 2) print 'Selected order:', to_hex(bom, 2) # Encode the text. encoded_text = u'pi: \u03c0'.encode(encoding) print '{:14}: {}'.format(encoding, to_hex(encoded_text, 2)) with open('non-native-encoded.txt', mode='wb') as f: # Write the selected byte-order marker. It is not included in the # encoded text because we were explicit about the byte order when # selecting the encoding. f.write(bom) # Write the byte string for the encoded text. f.write(encoded_text)上面a.py这部分代码首先得出内置字节码,然后显示地使用候选形式,以方便下一个例子读取时自动检测字节序.a.py打开文件时没有指定序,所以解码器会使用文件前2个字节中的bom来确定字节序.
with open('non-native-encoded.txt', mode='rb') as f: raw_bytes = f.read() print 'Raw :', to_hex(raw_bytes, 2) # Re-open the file and let codecs detect the BOM with codecs.open('non-native-encoded.txt', mode='rt', encoding='utf-16') as f: decoded_text = f.read() print 'Decoded:', repr(decoded_text) #由于文件前2个字节用于字节序检测,所以它们并不包含在read()返回数据中 ##错误处理
前面几节指出了需要知道的编码 阅读和写作时使用Unicode文件。 设置编码 正确是很重要的,原因有两个。 如果编码配置 错误的同时读取一个文件,数据将被解释 错了,可能会损坏或者无法解码。 并不是所有的Unicode 字符可以用在所有的编码,因此,如果错了 使用编码在写将生成一个错误和数据 是输了。
编解码器使用相同的五个错误处理选项 提供的编码()的方法Unicode和decode()的方法STR。
strict | Raises an exception if the data cannot be converted.提出了一个异常如果数据不能转换。 |
replace | Substitutes a special marker character for data that cannot be encoded.替代一个特殊的标记字符数据,不能编码。 |
ignore | Skips the data.跳过数据。 |
xmlcharrefreplace | XML character (encoding only)XML字符(编码) |
backslashreplace | escape sequence (encoding only)转义序列(编码) |
编码错误
最常见的错误条件是收到UnicodeEncodeError当你写 Unicode数据到一个ASCII输出流,如一个常规文件或sys.stdout。 可以使用这个示例程序 尝试不同的错误处理模式。
import codecs import sys error_handling = sys.argv[1] text = u'pi: \u03c0' try: # Save the data, encoded as ASCII, using the error # handling mode specified on the command line. with codecs.open('encode_error.txt', 'w', encoding='ascii', errors=error_handling) as f: f.write(text) except UnicodeEncodeError, err: print 'ERROR:', err else: # If there was no error writing to the file, # show what it contains. with open('encode_error.txt', 'rb') as f: print 'File contents:', repr(f.read())要确保一个应用程序地为所有I/O操作设置正确编码,strict模式最安全,但是产生一个异常时,可能导致程序崩溃. 一些其他的错误模式更加灵活。 例如,取代确保没有错误,为代价的 可能失去的数据不能被转换为所请求的 编码。 pi仍不能编码的Unicode字符 ASCII,而是提高异常字符被替换 与吗?在输出。
完全跳过问题数据,使用忽略。 任何数据, 不能编码只是丢弃。 有两种无损的错误处理选项,这两个替换 另一种表示形式的特性定义的标准 独立于编码。xmlcharrefreplace使用XML 作为替代字符引用(字符引用的列表 在W3C中指定吗XML字符实体定义)。 其他无损的错误处理方案backslashreplace哪一个 产生输出格式打印时喜欢你得到的价值repr()的Unicode对象。 Unicode字符 取而代之的是\ u紧随其后的是十六进制值的代码 点。
解码错误
还可以看到错误解码数据时,特别是 使用错误的编码。
error_handling = sys.argv[1] text = u'pi: \u03c0' print 'Original :', repr(text) # Save the data with one encoding with codecs.open('decode_error.txt', 'w', encoding='utf-16') as f: f.write(text) # Dump the bytes from the file with open('decode_error.txt', 'rb') as f: print 'File contents:', to_hex(f.read(), 1) # Try to read the data with the wrong encoding with codecs.open('decode_error.txt', 'r', encoding='utf-8', errors=error_handling) as f: try: data = f.read() except UnicodeDecodeError, err: print 'ERROR:', err else: print 'Read :', repr(data) 与编码,严格的错误处理模式提出了一个例外 如果不能正确解码的字节流。 在这种情况下,UnicodeDecodeError结果 试图将utf - 16 BOM的一部分转换为字符使用 utf - 8解码器。 切换到忽略导致译码器跳过无效 字节。 结果仍然是不期望是什么,不过, 它包括嵌入式空字节。 在取代无效的字节替换模式\ uFFFD, 官方Unicode替换字符,它看起来像一个钻石 包含白色与黑色背景问号(�)。更多请看:http://pymotw.com/2/codecs/ (这个是标准库的)官方地址:https://docs.python.org/2/library/codecs.html