【问题标题】:Python 3 throws UnicodeEncodeError with environment variable LANG=CPython 3 使用环境变量 LANG=C 抛出 UnicodeEncodeError
【发布时间】:2016-08-29 12:45:49
【问题描述】:

我有以下 Python 脚本:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

print('☺')

当我在我的 Debian 系统上运行它时,它会按预期产生以下输出:

$ ./test.py 
☺
$ 

但是,当我将语言环境更改为“C”时,通过设置LANG 环境变量,脚本会抛出UnicodeEncodeError

$ LANG=C ./test.py
Traceback (most recent call last):
  File "./test.py", line 4, in <module>
    print('\u263a')
UnicodeEncodeError: 'ascii' codec can't encode character '\u263a' in position 0: ordinal not in range(128)
$ 

此问题会阻止此脚本在最小环境中执行,例如在引导期间或在嵌入式系统中。另外,我怀疑许多现有的 Python 程序可以通过使用LANG=C 执行来破坏。 Here's an example 在 Stackoverflow 上的一个程序可能因在“C”语言环境中执行而中断。

这是 Python 中的错误吗?防止这种情况的最佳方法是什么?

【问题讨论】:

  • "这是 Python 中的错误吗?" — 你告诉 Python 在没有 WHITE SMILING FACE 的语言环境中打印它。我不认为这是 Python 的错。

标签: python python-3.x unicode locale


【解决方案1】:

这是因为 Python 3 使用语言环境设置来推断输出字符编码;也就是说,当您执行 locale 命令时,Python 将使用为 LC_CTYPE 显示的语言环境:

% locale 
...
LC_CTYPE="en_US.UTF-8"
...

如果您将LC_CTYPE 强制为C,那么Python 将假定ASCII 应该用作输出编码。而且 ASCII 没有 U+263A 的映射。

如果您希望 Python 知道如何正确编码 Unicode,请将 LC_CTYPE 设置为适当的值,或将二进制写入 fd 1。

【讨论】:

  • 这是否意味着,为了使脚本可移植,我应该在尝试打印 Unicode 字符串之前始终测试当前的语言环境设置是什么?
  • @hedgie 您无法制作真正可移植的脚本来打印非 ASCII 字符。不支持的终端太多了。
猜你喜欢
  • 2021-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-25
  • 1970-01-01
  • 2021-07-19
相关资源
最近更新 更多