- 论坛徽章:
- 0
|
添加:六、异常处理
- 六、异常处理
- 编码encoding发生在Unicode字符串转换为字节序列时,而解码decoding发生在字节序列转换为Unicode字符串时(encoding always takes a Unicode string and returns a bytes sequence, and decoding always takes a bytes sequence and returns a Unicode string)。
- UnicodeDecodeError
- UnicodeDncodeError通常发生在将str字符串解码为特定Unicode字符串时。由于不同的编码只能映射部分str字符串到对应的Unicode字符,所以遇到一些字符时解码会失败。
- UnicodeEncodeError
- UnicodeEncodeError通常发生在将Unicode字符串编码为特定字节序列时。由于不同的编码只能映射部分Unicode字符到对应的str字符串,所以遇到一些字符时编码会失败。
- 处理python编码转换时的UnicodeDecodeError异常
- python提供的unicode转换不像iconv或是mbstowcs之类的方便。如果转换一段unicode("1234中文",'ascii') 到utf8,会直接出现UnicodeDecodeError的错误。如果在你能预知字串符的编码的时候,比如你用unicode('1234中文', 'gbk') 就不会出现错误;不过很多时候,会出现CJK混合的情况,如果要做到将一段CJK文件转换成unicode可能就行不通了。好在python的codecs提供了register_error这个功能:
- register_error(name, error_handler)
- 原理很简单,不过要先看unicode是如何处理异常的。unicode这个函数是将一段string按输入的编码转换成目标的编码,如果出现了不与输入编码相符的,会出现一个UnicodeDecodeError的异常,通常有三种处理方法:strict、replace、ignore;默认是 strict,就是直接raise UnicodeDecodeError。通过register_error,我们也可以有自己的处理方法,如果遇到与输入的编码不符的时候,我们就自己识别,比如GBK、BIG5、JP的字符。
- def cjk_replace(exc):
- if not isinstance(exc, UnicodeDecodeError):
- raise TypeError("don't know how to handle %r" % exc)
- if exc.end + 1 > len(exc.object):
- raise TypeError('unknown codec ,the object too short!')
- ch1 = ord(exc.object[exc.start:exc.end])
- newpos = exc.end + 1
- ch2 = ord(exc.object[exc.start + 1:newpos])
- sk = exc.object[exc.start:newpos]
- if 0x81<=ch1<=0xFE and (0x40<=ch2<=0x7E or 0x7E<=ch2<=0xFE): # GBK
- return (unicode(sk,'cp936'), newpos)
- if 0x81<=ch1<=0xFE and (0x40<=ch2<=0x7E or 0xA1<=ch2<=0xFE): # BIG5
- return (unicode(sk,'big5'), newpos)
- raise TypeError('unknown codec !')
- codecs.register_error("cjk_replace", cjk_replace)
- 我们的cjk_replace现在只能处理GBK与BIG5的,因为我对编码也不是特别了解,只是大概知道GBK与BIG5的,不太了解JP的。在 cjk_replace这个函数里,我们对不认识的文字进行手工识别,如果认识的编码,就用正确的方法,并返回编码后的内容与新的pos,比如“1234中文”,在pos为4的时候,会调用我们的cjk_replace,我们会返回一个从gbk转换成utf8的“中”字,并返回下个正确的位置“文”的起始位置。当然了,处理“文”的时候,还会再调用一次。下面看看是如何使用的:
- filedata = open('test.txt','r).read() #gbk and big5 file
- data = unicode(filedata,'ascii','cjk_replace').encode('utf8')
- 7、 UnicodeDecodeError
- [url]http://wiki.python.org/moin/UnicodeDecodeError[/url]
- 8、 UnicodeEncodeError
- [url]http://wiki.python.org/moin/UnicodeEncodeError[/url]
- 9、 如何处理python编码转换时的UnicodeDecodeError异常
- [url]http://blog.chinaunix.net/u/8873/showart_1009737.html[/url]
- 10、codecs — Codec registry and base classes
- [url]http://docs.python.org/library/codecs.html[/url]
复制代码 |
|