【发布时间】:2014-03-19 02:03:15
【问题描述】:
看似简单的问题:我如何print() Python3 中的字符串?应该很简单:
print(my_string)
但这不起作用。根据my_string 的内容,环境变量和您使用的操作系统将引发UnicodeEncodeError 异常:
>>> print("\u3423")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character '\u3423' in position 0: ordinal not in range(128)
有没有一种干净的便携式方法来解决这个问题?
扩展一下:这里的问题是 Python3 字符串包含 Unicode 编码的字符,而终端可以有任何编码。如果你很幸运,你的终端可以处理字符串中包含的所有字符,一切都会好起来的,如果你的终端不能(例如有人设置LANG=C),那么你会得到一个异常。
如果你在 Python3 中手动编码一个字符串,你可以提供一个错误处理程序来忽略或替换不可编码的字符:
"\u3423".encode("ascii", errors="replace")
对于print(),我看不到插入错误处理程序的简单方法,即使有,简单的错误处理程序似乎也是一个糟糕的主意,因为它会修改数据。有条件的错误处理程序可能会起作用(即检查isatty() 并根据它决定要做什么),但是仅仅为了print() 一个字符串而经历所有这些麻烦似乎非常糟糕,我什至不确定它不会'在某些情况下不会失败。
一个现实世界的例子,这个问题就是这个问题:
【问题讨论】:
-
在 linux 上对我来说很好用。您可能需要指定给您带来麻烦的操作系统和环境变量。
-
在 Mac OS X 上工作正常。打印出一个(中文?)字符?
-
在我的 Linux 控制台和 X 终端模拟器上工作,但两者都配置为正确的 UTF-8 支持。我想知道,UTF-8 是否在您收到此错误的环境中一般工作?也许不仅仅是 Python。
-
如果是 tty,您可以替换 stdout:
sys.stdout = io.TextIOWrapper(sys.stdout.detach(), errors='backslashreplace')。 -
使用
LANG=C python3 -c 'print("\u3423")',我可以重现您的错误,而使用LANG=en_US.UTF-8,工作正常。