我在生产系统中遇到错误,我无法在开发环境中重现:
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
如果我通过shell和网络请求拨打locale.getpreferredencoding()
,则编码为" UTF-8"。
我在代码中更新了我的异常处理,并在某些日子后记录getpreferredencoding()
。现在它再次发生(到目前为止我无法强制或重现),编码是" ANSI_X3.4-1968"!
我不知道这个编码设置的位置....
这使我的问题朝着不同的方向发展。留下这个问题毫无用处。我现在的问题是:首选编码在哪里被改变?但这不是这个问题的一部分。
非常感谢所有
的人答案 0 :(得分:7)
您依赖于平台的默认编码;当默认编码不支持您写入文件的Unicode字符时,会出现编码异常。
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