当设置了非拉丁语言环境时,对于我来说,IOError.strerror在Python2.7中变成了非Unicode:
import locale
locale.setlocale(locale.LC_ALL, '')
print locale.getlocale(locale.LC_MESSAGES)
try:
open('/asdasd', 'w')
except IOError as e:
print e.strerror
print repr(e.strerror)
print unicode(e) # boom运行:
LANG=fr_FR.utf8 python test.py输出:
('fr_FR', 'UTF-8')
Permission non accordée
'Permission non accord\xc3\xa9e'
Traceback (most recent call last):
File "test.py", line 11, in <module>
print unicode(e)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 32: ordinal not in range(128)看起来操作系统错误消息是按原样存储在strerror中的,而不是先转换成Unicode。是否可以在不手动解码每个Exception的情况下解决此问题
发布于 2013-08-24 07:43:21
我不确定这会是一个很好的答案,但是:
Python2有一些地方(例外是其中之一),"text“和"bytes”之间的区别不是很清楚。实际上,在Python2中,我所见过的异常中的每个字符串都是一个str或bytes。(并不是说自定义库不能返回unicode,而是标准Python内容不能。)因此,您可以将系统错误视为str/bytes。您可以通过将最后一行( # boom)更改为:
print unicode(str(e), 'utf-8')或者,如我所愿,
print str(e).decode('utf-8')现在,'utf-8'在这里是一个神奇的常量:它必须与区域设置匹配(对于fr_FR.utf8,它确实是匹配的。对于其他非UTF-8语言环境,它可能不会。)我相信locale.getpreferredencoding()会给您正确的答案,如下所示:
print str(e).decode(locale.getpreferredencoding())隧道的尽头有了曙光:在Python3中,你发布的代码应该可以正常工作。(典型的Py3k改动很小-- print()是一个函数,而unicode需要是str。)
²我可以让它与fr_FR.utf-8一起工作,但不能与fr_FR.ISO-8859-1一起工作。不知道为什么。后一种编码适用于Python2。Python3运行时做了我提到的修改,但似乎完全去掉了重音。
发布于 2013-08-24 14:50:55
终于弄明白了:
默认情况下,Python2使用ascii作为系统编码(参见sys.getdefaultencoding)。
不幸的是,没有setdefaultencoding (更准确地说,它正在被site.py从sys模块中删除),所以我使用的解决方案如下:
import locale
import sys
reload(sys) # reload sys so sys.setdefaultencoding is available again
sys.setdefaultencoding('utf8')
locale.setlocale(locale.LC_ALL, '')
try:
open('/asdasd', 'w')
except IOError as e:
print unicode(e)https://stackoverflow.com/questions/18397572
复制相似问题