首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python IOError.strerror不是Unicode

Python IOError.strerror不是Unicode
EN

Stack Overflow用户
提问于 2013-08-23 15:50:28
回答 2查看 1.2K关注 0票数 2

当设置了非拉丁语言环境时,对于我来说,IOError.strerror在Python2.7中变成了非Unicode:

代码语言:javascript
复制
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

运行:

代码语言:javascript
复制
LANG=fr_FR.utf8 python test.py

输出:

代码语言:javascript
复制
('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的情况下解决此问题

EN

回答 2

Stack Overflow用户

发布于 2013-08-24 07:43:21

我不确定这会是一个很好的答案,但是:

Python2有一些地方(例外是其中之一),"text“和"bytes”之间的区别不是很清楚。实际上,在Python2中,我所见过的异常中的每个字符串都是一个strbytes。(并不是说自定义库不能返回unicode,而是标准Python内容不能。)因此,您可以将系统错误视为str/bytes。您可以通过将最后一行( # boom)更改为:

代码语言:javascript
复制
print unicode(str(e), 'utf-8')

或者,如我所愿,

代码语言:javascript
复制
print str(e).decode('utf-8')

现在,'utf-8'在这里是一个神奇的常量:它必须与区域设置匹配(对于fr_FR.utf8,它确实是匹配的。对于其他非UTF-8语言环境,它可能不会。)我相信locale.getpreferredencoding()会给您正确的答案,如下所示:

代码语言:javascript
复制
print str(e).decode(locale.getpreferredencoding())

隧道的尽头有了曙光:在Python3中,你发布的代码应该可以正常工作。(典型的Py3k改动很小-- print()是一个函数,而unicode需要是str。)

²我可以让它与fr_FR.utf-8一起工作,但不能与fr_FR.ISO-8859-1一起工作。不知道为什么。后一种编码适用于Python2。Python3运行时做了我提到的修改,但似乎完全去掉了重音。

票数 2
EN

Stack Overflow用户

发布于 2013-08-24 14:50:55

终于弄明白了:

默认情况下,Python2使用ascii作为系统编码(参见sys.getdefaultencoding)。

不幸的是,没有setdefaultencoding (更准确地说,它正在被site.pysys模块中删除),所以我使用的解决方案如下:

代码语言:javascript
复制
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)
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18397572

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档