Python 'ascii' 打印语句编码问题

标签 python linux unicode

系统:python 3.4.2 on linux。

我正在开发一个 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 会受到影响?

最佳答案

LANG 用于确定您的语言环境;如果您没有设置特定的 LC_ 变量,则 LANG 变量将用作默认值。

文件系统编码由 LC_CTYPE variable 决定,但如果您没有专门设置该变量,则会使用 LANG 环境变量。

打印使用 sys.stdout,这是一个配置有您的终端使用的编解码器的文本文件。您的终端设置也是特定于区域设置的;您的 LANG 变量应该真正反射(reflect)您的终端设置的语言环境。如果那是 UTF-8,您需要确保您的 LANG 变量反射(reflect)了这一点。 sys.stdout 使用 locale.getpreferredencoding(False) (就像所有没有显式编码集打开的文本流一样)和在 POSIX 系统上也会使用 LC_CTYPE

关于Python 'ascii' 打印语句编码问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27448111/

相关文章:

Python tkinter 列表框小部件 : unicode text with ' char get jumbled

python - 计算列表与列表的 pandas 列的交集长度

c - Linux C,waitpid() 被具有返回值 -1 和 errno 5 的已处理信号解除阻塞

python - 将字符串转换为预定义的Python变量

javascript - 如何从 HTML 和 Javascript 页面执行 Linux 命令?

C: 未初始化的 int 类型大小必须大于

java - JTextPane 的等宽字体/符号

unicode - 快速的、支持 Unicode 的、跨平台的程序员文本编辑器,显示像 ZWSP 这样的不可见内容?

python - 属性错误: module 'simplejson' has no attribute 'dumps' on "import flask"

python - 从 MySQL 写入文件时出现内存问题