V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
xavierskip
V2EX  ›  Python

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

  •  
  •   xavierskip · 2017-12-28 14:22:06 +08:00 · 2402 次点击
    这是一个创建于 2521 天前的主题,其中的信息可能已经有所发展或是发生改变。

    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的结果不同,为什么呢?

    第 1 条附言  ·  2017-12-31 22:29:18 +08:00
    [有关 Python 2 和 Sublime Text 中文 Unicode 编码问题的分析与理解] https://www.v2ex.com/t/163786
    有一定的帮助
    5 条回复    2017-12-28 19:48:52 +08:00
    lniwn
        1
    lniwn  
       2017-12-28 14:54:20 +08:00
    我觉得 help(sys.stdout),然后再看看这篇文章<https://github.com/tartley/colorama/issues/125>或许对你有帮助。
    justou
        2
    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
        3
    geelaw  
       2017-12-28 16:19:48 +08:00 via iPhone
    因为打开一个文件默认是用 preferred encoding indicated by locale,而 console 是 UTF-8。
    xavierskip
        4
    xavierskip  
    OP
       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
        5
    xavierskip  
    OP
       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 呢?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   925 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 21:22 · PVG 05:22 · LAX 13:22 · JFK 16:22
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.