【问题标题】:set the implicit default encoding\decoding error handling in python在python中设置隐式默认编码\解码错误处理
【发布时间】:2011-03-22 18:10:37
【问题描述】:

我正在处理以 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 做不同的事情,但无济于事。

请帮忙?

【问题讨论】:

  • 如果你在做s=str(u'abc\u2013'),你想在unicode中工作,如果你将默认编码设置为latin-1这似乎很奇怪
  • 这是个坏主意:tarekziade.wordpress.com/2008/01/08/…。如果您使用编码字符串,则应显式解码它们。否则你可能会掩盖讨厌的错误。
  • 具体来说,您应该在模块中使用 Unicode。外部数据进来时解码,出去时再编码。

标签: python decode encode


【解决方案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'

参考资料:

  1. https://docs.python.org/3/library/codecs.html#codecs.register_error
  2. https://docs.python.org/3/library/exceptions.html#UnicodeError
  3. How to ignore invalid lines in a file?
  4. 'str' object has no attribute 'decode'. Python 3 error?
  5. How to replace invalid unicode characters in a string in Python?
  6. UnicodeDecodeError in Python when reading a file, how to ignore the error and jump to the next line?

【讨论】:

    【解决方案2】:

    脚本无法调用 sys.setdefaultencoding 是有原因的。不要那样做,一些库(包括 Python 中包含的标准库)期望默认为 'ascii'。

    相反,在读入程序时(通过文件、标准输入、套接字等)将字符串显式解码为 Unicode,并在写出字符串时显式编码字符串。

    显式解码采用参数指定不可解码字节的行为。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-25
      • 1970-01-01
      • 2015-07-13
      • 2010-10-12
      • 2011-08-29
      • 2013-02-04
      • 1970-01-01
      • 2014-11-07
      相关资源
      最近更新 更多