系统:Linux上的python 3.4.2。
我正在研究django应用程序(无关紧要),我遇到了它抛出的问题
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
调用 print 时(!)。经过相当多的挖掘,我发现我应该检查
>>> sys.getdefaultencoding()
'utf-8'
但是就像预期的那样,utf8。我还注意到os.path.exists
在与unicode字符串一起使用时会抛出相同的异常。所以我检查了
>>> sys.getfilesystemencoding()
'ascii'
当我使用LANG=en_US.UTF-8
时,问题就消失了。我现在明白为什么os.path.exists
有问题。但我完全不知道为什么print
语句受 filesystem 设置的影响。我错过了第三种情况吗?或者只是假设LANG
环境值得信任?
另外......我在这里得不到推理。 LANG
不会告诉文件名支持哪种编码。它与此无关。它是针对当前环境单独设置的,而不是针对文件系统设置的。为什么python使用此设置来处理文件系统文件名?它使应用程序非常脆弱,因为在未设置LANG
或设置为C
的环境中运行时,所有文件操作都会中断(并非罕见,尤其是当web应用程序以root身份运行或专门为守护进程创建的新用户。
测试代码(避免终端编码陷阱所需的实际unicode输入):
x=b'\xc4\x8c\xc5\xbd'
y=x.decode('utf-8')
print(y)
问题:
LANG
设置具有健壮性?print
会受到影响?答案 0 :(得分:1)
LANG
用于确定您的区域设置;如果您未设置特定LC_
变量,则LANG
变量将用作默认值。
文件系统编码由LC_CTYPE
variable确定,但如果您没有专门设置该变量,则使用LANG
环境变量。
打印使用sys.stdout
,这是一个配置了终端使用的编解码器的文本文件。您的终端设置也是特定于区域设置的;您的LANG
变量应该真正反映终端设置的区域设置。如果是UTF-8,您需要确保LANG
变量反映出来。 sys.stdout
使用locale.getpreferredencoding(False)
(与未使用显式编码集打开的所有文本流一样)和使用LC_CTYPE
的POSIX系统。