你好,我有一个名为'test.py'的Python文件:
import sys
print(sys.stdout.encoding)
sys.stdout.reconfigure(encoding='utf-8')
print(sys.stdout.encoding)
当我运行时
py test.py
我得到:
utf-8
utf-8
但是当我运行时
py test.py > test.txt
或者
py test.py | Out-File -FilePath test.txt -Encoding ASCII
我从test.txt获取:
cp1252
utf-8
当我运行时:
import sys, locale
print(sys.getdefaultencoding())
print(locale.getpreferredencoding())
我得到:
utf-8
cp1252
问题:
请问为什么会出现这种情况,以及在重定向时如何使默认编码为 utf-8?
谢谢
cmd.exe /c "命令行"
管道或文件的命令。PowerShell与我使用过的每个Shell都不同,标准I/O重定向将Shell设置为中间人,解码文本,转换LF <-> CRLF换行符,然后重新进行编码。我从来不想要这个。默认情况下,Shell应直接连接管道和文件重定向,而不涉及自身。CMD做得很好。 - Eryk Sunlocale.getpreferredencoding()
用于非控制台I/O,而对于控制台I/O则为UTF-8(在内部转码为控制台的宽字符API所需的UTF-16)。sys.getdefaultencoding()
是脚本文件和str.encode
的默认编码。 - Eryk SunPYTHONIOENCODING
环境变量来覆盖非控制台sys.std*
文件的默认编码。在较新的版本中,我们可以通过命令行选项-Xutf8
将默认编码覆盖为UTF-8。 - Eryk Suncmd /c "py.exe -Xutf8 test.py > test.txt"
。要使-Encoding
生效,PowerShell 必须先将程序的 stdout 解码为 UTF-16,然后重新编码,这可能会产生乱码,除非您手动匹配 PowerShell 的输入文本编码与程序的 stdout 编码相同。如果您对程序本身有控制权,例如使用 Python 脚本,则最好将 PowerShell 排除在外。 - Eryk Sun> test.txt
不会将命令的stdout设置为指向“test.txt”文件的句柄,而是将其设置为具有PowerShell另一端的管道。这与我使用过的所有其他shell都不同。由程序(例如Python)写入stdout的编码字节会被PowerShell 转码,包括LF -> CRLF转换,然后写入目标文件。在PowerShell内部的解决方法非常复杂。我的意思是通过运行cmd.exe /c "command line"
来简单地绕过这种烦人的行为。 - Eryk Sun