为什么程序在 Windows 系统中标准输出和重定向到文件后的输出结果不一样?

2017-12-28 14:22:06 +08:00
 xavierskip

p.py

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

import sys, locale 
print(sys.stdout.encoding, sys.getdefaultencoding(), locale.getpreferredencoding())
print('你好,世界')

python 版本 3.6.3,中文 Windows 7 系统,cmd 下执行以下命令

C:\Users\>python p.py
utf-8 utf-8 cp936
你好,世界

C:\Users\>python p.py > p.txt

p.txt 编码为 ANSI,内容为

cp936 utf-8 cp936
你好,世界

sys.stdout.encoding的结果不同,为什么呢?

2401 次点击
所在节点    Python
5 条回复
lniwn
2017-12-28 14:54:20 +08:00
我觉得 help(sys.stdout),然后再看看这篇文章<https://github.com/tartley/colorama/issues/125>或许对你有帮助。
justou
2017-12-28 15:33:05 +08:00
这样说明是不是很容易理解?

import sys, locale
fh = open("f.txt", "w", encoding="utf-8") # 换成"gbk", "big5"等其它编码试试
sys.stdout = fh
print(sys.stdout.encoding, sys.getdefaultencoding(), locale.getpreferredencoding())
print('你好,世界')
fh.close()
geelaw
2017-12-28 16:19:48 +08:00
因为打开一个文件默认是用 preferred encoding indicated by locale,而 console 是 UTF-8。
xavierskip
2017-12-28 19:22:12 +08:00
应该和 isatty() 有关。
sys.stdout.isatty()在直接执行的情况下返回 True,如果输出重定向到文件则返回 False。
文档中找到了相应的解释

The character encoding is platform-dependent. Under Windows, if the stream is interactive (that is, if its isatty() method returns True), the console codepage is used, otherwise the ANSI code page. Under other platforms, the locale encoding is used (see locale.getpreferredencoding()).

可能就如这篇文章中说的一样
http://blog.csdn.net/haiross/article/details/36189103
```
if sys.stdout.isatty():
default_encoding = sys.stdout.encoding
else:
default_encoding = locale.getpreferredencoding()
```
但是我还不清楚如何去源代码中具体查看。
xavierskip
2017-12-28 19:48:52 +08:00
可是文档里说`if the stream is interactive (that is, if its isatty() method returns True), the console codepage is used, otherwise the ANSI code page`
chcp 执行后显示代码页为 936,为什么 sys.stdout.encoding 会是 utf-8 呢?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/418290

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX