Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中通过sys.stdout编写unicode字符串_Python_Unicode_Macos_Terminal_Stdout - Fatal编程技术网

在Python中通过sys.stdout编写unicode字符串

在Python中通过sys.stdout编写unicode字符串,python,unicode,macos,terminal,stdout,Python,Unicode,Macos,Terminal,Stdout,假设您不能使用打印(从而享受自动编码检测的好处)。这就给我们留下了sys.stdout。然而,sys.stdout太笨了,以至于无法使用 现在,阅读Python wiki页面并尝试以下代码: $ python -c 'import sys, codecs, locale; print str(sys.stdout.encoding); \ sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout); 然而

假设您不能使用
打印
(从而享受自动编码检测的好处)。这就给我们留下了
sys.stdout
。然而,
sys.stdout
太笨了,以至于无法使用

现在,阅读Python wiki页面并尝试以下代码:

$ python -c 'import sys, codecs, locale; print str(sys.stdout.encoding); \
  sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout);
然而,这也不起作用(至少在Mac上是这样)。我也明白为什么:

>>> import locale
>>> locale.getpreferredencoding()
'mac-roman'
>>> sys.stdout.encoding
'UTF-8'
(UTF-8是终端理解的内容)

因此,将上述代码更改为:

$ python -c 'import sys, codecs, locale; print str(sys.stdout.encoding); \
  sys.stdout = codecs.getwriter(sys.stdout.encoding)(sys.stdout);
现在,unicode字符串被正确地发送到
sys.stdout
,并因此正确地打印在终端上(
sys.stdout
连接在终端上)

这是在
sys.stdout
中编写unicode字符串的正确方法,还是我应该做其他事情


编辑:有时——比如,将输出管道传输到
less
——
sys.stdout.encoding
将是
。在这种情况下,上述代码将失败。

我不清楚您为什么不能进行打印;但假设是这样,我认为这种方法是正确的。

最好的办法是检查您是否直接连接到终端。如果是,请使用终端的编码。否则,请使用系统首选编码

if sys.stdout.isatty():
    default_encoding = sys.stdout.encoding
else:
    default_encoding = locale.getpreferredencoding()
始终允许用户指定她想要的编码也是非常重要的。通常,我将其设置为命令行选项(如
-e ENCODING
),并使用
optparse
模块对其进行解析


另一个好方法是使用自动编码器不覆盖
sys.stdout
。创建编码器并使用它,但不要使用
sys.stdout
。您可以将通过TestRing编码的第三方库直接导入
sys.stdout

有一个可选的环境变量“PYTHONIOENCODING”,它可以设置为所需的默认编码。这将是一种以与所有Python一致的方式获取用户所需编码的方法。它隐藏在Python手册中

将完成此任务,但无法将其设置为python本身

我们可以做的是验证是否未设置,并告诉用户在调用脚本之前使用以下命令进行设置:

if __name__ == '__main__':
    if (sys.stdout.encoding is None):
        print >> sys.stderr, "please set python env PYTHONIOENCODING=UTF-8, example: export PYTHONIOENCODING=UTF-8, when write to stdout."
        exit(1)

这就是我在应用程序中所做的:

sys.stdout.write(s.encode('utf-8'))

这与从argv读取UTF-8名称的修复方法完全相反:

for file in sys.argv[1:]:
    file = file.decode('utf-8')

这是非常丑陋的(IMHO),因为它迫使您使用UTF-8。。这是Linux/Mac上的标准,但不是windows上的标准。。。反正对我来说也行:)

我不能使用
print
的一个原因是为了避免额外的空间
print
prints。看看这里的
sys.stdout
用法:您可以构建完整的行,然后打印它们。添加逗号不会打印换行符,但会打印额外的空格。尝试运行:python-c“print 2,;print 3”,如果输出到管道,它可能不知道使用什么编码(因为它不知道less(1)在管道的另一端)。因此,您的应用程序必须确定/决定自己的编码。在Python3中,您可以执行
print(stuff,sep='',end='')
以避免额外的空格。我怀疑编码问题也不存在。s/my/one's/用于一致性
for file in sys.argv[1:]:
    file = file.decode('utf-8')