Python 3.x 如何在Python3中无例外地打印()字符串?

Python 3.x 如何在Python3中无例外地打印()字符串?,python-3.x,python-unicode,Python 3.x,Python Unicode,看似简单的问题:如何在Python3中打印字符串?应该是一个简单的例子: print(my_string) 但这不起作用。根据my_string的内容、环境变量以及将引发unicodeincodeer异常的操作系统: >>> print("\u3423") Traceback (most recent call last): File "<stdin>", line 1, in <module> UnicodeEncodeError: 'ascii

看似简单的问题:如何在Python3中打印字符串?应该是一个简单的例子:

print(my_string)
但这不起作用。根据
my_string
的内容、环境变量以及将引发
unicodeincodeer
异常的操作系统:

>>> 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)
对于
print()
我看不到插入错误处理程序的简单方法,即使有,简单的错误处理程序似乎是个糟糕的主意,因为它会修改数据。条件错误处理程序可能会工作(即,检查
isatty()
并根据该操作来决定该做什么),但仅仅打印一个字符串就经历了所有这些麻烦,这似乎是非常不明智的,我甚至不确定它在某些情况下是否会失败

现实世界中的一个例子就是这个问题:

有没有一个干净的便携式方法来解决这个问题

设置
pythonionecoding=:
例如

$ PYTHONIOENCODING=utf-8 python your_script.py >output-in-utf-8.txt
在您的情况下,我将配置您的环境(
LANG
LC\u CTYPE
)以接受非ascii输入:

$ locale charmap

它给您一个错误的原因是因为它试图破译\u是什么。就像\r是回车的ascii码一样,\n-newline\t-tab等

如果:

这将给您一个错误,即打印“\”而不尝试找出\是什么样子:

 my_string = '\\u122'
 print(my_string)
输出:

 \u122

解决此问题的最实际的方法似乎是强制输出编码为
utf-8:subscrateescape
。这不仅将强制UTF-8输出,还将确保可以打印由
os.fsdecode()
返回的代理转义字符串,而不会引发异常。在命令行上,如下所示:

PYTHONIOENCODING=utf-8:surrogateescape python3 -c 'print("\udcff")'
要从程序本身内部执行此操作,必须重新分配
stdout
stderr
,这可以通过(行缓冲=True很重要,否则输出将无法正确刷新):

这种方法会导致字符在未设置为UTF-8的终端上不正确地显示,但在我看来,这似乎比随机抛出异常和使打印文件名不损坏文件名更受欢迎,因为在Linux系统上它们可能根本没有任何有效的编码


我在一些地方读到,
utf-8:subscrateescape
将来可能会成为默认值,但从Python 3.6.0b2开始,情况就不是这样了。

在linux上对我来说很好。您可能想指定哪些操作系统和哪些环境变量给您带来了麻烦。在Mac OS X上对我来说很好。打印(中文?)字符?在我的Linux控制台和X终端模拟器上可以工作,但两者都配置为适当的UTF-8支持。我想知道,UTF-8在您接收到此错误的环境中是否正常工作?也许不仅仅是Python。如果stdout是tty,你可以替换它:
sys.stdout=io.TextIOWrapper(sys.stdout.detach(),errors='backslashreplace')
。使用
LANG=C python3-C'print(“\u3423”)”
,我可以复制你的错误,而使用
LANG=en_US.UTF-8
,效果很好。
 \u122
PYTHONIOENCODING=utf-8:surrogateescape python3 -c 'print("\udcff")'
import sys
import io

sys.stdout = io.TextIOWrapper(sys.stdout.buffer, errors="surrogateescape", line_buffering=True)
sys.stderr = io.TextIOWrapper(sys.stderr.buffer, errors="surrogateescape", line_buffering=True)

print("\udcff")