我正在运行python工具并尝试将其输出保存到文件中。如果我不将输出保存到文件,该工具运行完全正常。但是当我尝试将输出保存到文件时,它会抛出以下错误并中断程序:
File "./androdiff.py", line 118, in <module>
main(options, arguments)
File "./androdiff.py", line 94, in main
ddm.show()
File "./elsim/elsim/elsim_dalvik.py", line 772, in show
self.eld.show()
File "./elsim/elsim/elsim.py", line 435, in show
i.show()
File "./elsim/elsim/elsim_dalvik.py", line 688, in show
print hex(self.bb.bb.start + self.offset), self.pos_instruction, self.ins.get_name(), self.ins.show_buff( self.bb.bb.start + self.offset )
UnicodeEncodeError: 'ascii' codec can't encode character u'\u0111' in position 35: ordinal not in range(128)
我已尝试command |less
,command > output
和command | tee output
,所有这些都会引发此类错误。
请帮助解决问题。
谢谢!
答案 0 :(得分:3)
如果无法自动确定stdout字符编码,例如,当输出重定向到文件时,请显式设置PYTHONIOENCODING
环境变量:
$ PYTHONIOENCODING=utf-8 python app.py > file
如果输出可能会转到终端,请不要在脚本中对字符编码进行硬编码;打印Unicode字符串,让用户配置他们的环境。
答案 1 :(得分:2)
您需要在打印之前指定字符串的编码:
print unicode(hex(self.bb.bb.start + self.offset)).encode('utf-8')
print unicode(self.pos_instruction, self.ins.get_name()).encode('utf-8')
print unicode(self.ins.show_buff( self.bb.bb.start + self.offset )).encode('utf-8')
这样做的原因是因为python在打印到终端时会正确地自动编码你的字符串(在你的情况下为utf-8)(它检测到终端使用utf-8)。
当您将输出重定向到文件时,Python没有关于它应该使用什么编码的信息,而是默认为ascii(这会导致您的错误)。
作为一般经验法则,请确保在打印前始终对字符串进行编码,以使print
在所有环境中都有效。
最好的方法可能是为此定义自己的打印方法:
def myprint(unicodestr):
print unicodestr.encode('utf-8')
如果你想避免上述情况并使用utf-8编码进行打印,则可以使用默认值
import sys
import codecs
sys.stdout=codecs.getwriter('utf-8')(sys.stdout)
小心这种方法!某些第三方库可能依赖于ascii和break的默认编码。请注意,整个混乱已在Python 3(默认为UTF-8编码)
中解决