如何重现UnicodeEncodeError?

时间:2017-01-10 11:48:12

标签: python python-2.7 python-unicode

我在生产系统中遇到错误,我无法在开发环境中重现:

with io.open(file_name, 'wt') as fd:
    fd.write(data)

例外:

  File "/home/.../foo.py", line 18, in foo
    fd.write(data)

UnicodeEncodeError: 'ascii' codec can't encode character u'\xe4' in position 6400: ordinal not in range(128)

我已经尝试过很多奇怪的字符到变量data

但到目前为止,我无法重现UnicodeEncodeError

data需要什么才能获得UnicodeEncodeError

更新

python -c 'import locale; print locale.getpreferredencoding()'
UTF-8

UPDATE2

如果我通过shell和网络请求拨打locale.getpreferredencoding(),则编码为" UTF-8"。

我在代码中更新了我的异常处理,并在某些日子后记录getpreferredencoding()。现在它再次发生(到目前为止我无法强制或重现),编码是" ANSI_X3.4-1968"!

我不知道这个编码设置的位置....

这使我的问题朝着不同的方向发展。留下这个问题毫无用处。我现在的问题是:首选编码在哪里被改变?但这不是这个问题的一部分。

非常感谢所有

的人

3 个答案:

答案 0 :(得分:7)

您依赖于平台的默认编码;当默认编码不支持您写入文件的Unicode字符时,会出现编码异常。

来自io.open() documentation

  

encoding 是用于解码或编码文件的编码的名称。这应该只在文本模式下使用。默认编码取决于平台(无论locale.getpreferredencoding()返回什么),但可以使用Python支持的任何编码。

对于您的具体情况,locale.getpreferredencoding()返回的默认值为ASCII,因此ASCII范围之外的任何Unicode字符都会导致此问题,U-0080及以上。

请注意,区域设置取自您的环境;如果是ASCII,则通常表示区域设置设置为POSIX default locale, C

明确指定编码:

with io.open(file_name, 'wt', encoding='utf8') as fd:
    fd.write(data)

我用UTF-8作为例子;你选择的内容完全取决于你的用例和你想要写出的数据。

答案 1 :(得分:1)

我试过这个来重现错误:

with open(filename, 'wt', encoding='ascii') as fd:
    fd.write('\xa0')
  

追踪(最近的呼叫最后):
  文件" test.py",第2行,in          fd.write(' \ XA0')
  UnicodeEncodeError:' ascii'编解码器不能对字符' \ xa0'进行编码。位置0:序数不在范围内(128)

答案 2 :(得分:0)

write换成try / except并将数据保存到二进制文件中 - 您将能够确切地看到哪些数据会给您带来问题:

with io.open(file_name, 'wt') as fd:
    try:
        fd.write(data)
    except UnicodeEncodeError:
        with open('/path/to/save/error.bin', 'wb') as err:
            err.write(data)
        raise