首页 > 解决方案 > 将 python 输出重定向到文件会导致 Windows 上的 UnicodeEncodeError

问题描述

我正在尝试将 python 脚本的输出重定向到一个文件。当输出包含非 ascii 字符时,它适用于 macOS 和 Linux,但不适用于 Windows。

我已经将问题推断为一个简单的测试。以下是 Windows 命令提示符窗口中显示的内容。测试只是一次打印调用。

Microsoft Windows [Version 10.0.17134.472]
(c) 2018 Microsoft Corporation. All rights reserved.

D:\>set PY
PYTHONIOENCODING=utf-8

D:\>type pipetest.py
print('\u0422\u0435\u0441\u0442')

D:\>python pipetest.py
Тест

D:\>python pipetest.py > test.txt

D:\>type test.txt
Тест

D:\>type test.txt | iconv -f utf-8 -t utf-8
Тест

D:\>set PYTHONIOENCODING=

D:\>python pipetest.py
Тест

D:\>python pipetest.py > test.txt
Traceback (most recent call last):
  File "pipetest.py", line 1, in <module>
    print('\u0422\u0435\u0441\u0442')
  File "C:\Python\Python37\lib\encodings\cp1252.py", line 19, in encode
    return codecs.charmap_encode(input,self.errors,encoding_table)[0]
UnicodeEncodeError: 'charmap' codec can't encode characters in position 0-3: character maps to <undefined>

D:\>python -V
Python 3.7.2

正如人们所看到的,设置 PYTHONIOENCODING 环境变量会有所帮助,但我不明白为什么需要设置它。当输出是终端时,它可以工作,但如果输出是文件,它会失败。为什么在 stdout 不是控制台时使用 cp1252?

也许这是一个错误,可以在 Windows 版本的 python 中修复?

标签: pythonwindowsencoding

解决方案


基于 Python 文档,Windows 版本在控制台设备(utr-8)和非字符设备(如磁盘文件和管道(系统语言环境))上使用不同的字符编码。PYTHONIOENCODING 可用于覆盖它。

https://docs.python.org/3/library/sys.html#sys.stdout

另一种方法是直接在程序中更改编码,我试过了,效果很好。

sys.stdout.reconfigure(encoding='utf-8')

https://docs.python.org/3/library/io.html#io.TextIOWrapper.reconfigure


推荐阅读