设置Python中的隐式默认编码\解码错误处理
我正在处理一些用latin1编码的外部数据。所以我添加了一个叫 sitecustomize.py
的文件,并在里面加了以下内容:
sys.setdefaultencoding('latin_1')
果然,现在处理latin1字符串时一切正常。
但是,如果我遇到一些不是用latin1编码的内容:
s=str(u'abc\u2013')
我就会收到一个错误:UnicodeEncodeError: 'latin-1' codec can't encode character u'\u2013' in position 3: ordinal not in range(256)
我希望的是,无法编码的字符能被简单地忽略,也就是说在上面的例子中我希望得到 s=='abc?'
,而且不想每次都明确调用 decode()
或 encode
,也就是不想在每次调用时都写 s.decode(...,'replace')
。
我尝试过用 codecs.register_error
做不同的事情,但都没有成功。
请帮帮我?
2 个回答
1
你可以定义自己的处理器,然后用它来做你想做的事情。看看这个例子:
import codecs
from logging import getLogger
log = getLogger()
def custom_character_handler(exception):
log.error("%s for %s on %s from position %s to %s. Using '?' in-place of it!",
exception.reason,
exception.object[exception.start:exception.end],
exception.encoding,
exception.start,
exception.end )
return ("?", exception.end)
codecs.register_error("custom_character_handler", custom_character_handler)
print( b'F\xc3\xb8\xc3\xb6\xbbB\xc3\xa5r'.decode('utf8', 'custom_character_handler') )
print( codecs.encode(u"abc\u03c0de", "ascii", "custom_character_handler") )
运行这个代码后,你会看到:
invalid start byte for b'\xbb' on utf-8 from position 5 to 6. Using '?' in-place of it!
Føö?Bår
ordinal not in range(128) for π on ascii from position 3 to 4. Using '?' in-place of it!
b'abc?de'
参考资料:
2
脚本不能调用 sys.setdefaultencoding 是有原因的。不要这样做,因为一些库(包括 Python 自带的标准库)期望默认编码是 'ascii'。
相反,当你把字符串读入程序时(比如通过文件、标准输入、网络等),要明确地将它们解码成 Unicode;而在输出字符串时,也要明确地进行编码。
明确解码时需要一个参数,用来指定如何处理那些无法解码的字节。