我希望在管道传输时将文本打印为UTF-8(例如,到文件),因此在Windows 10上通过PowerShell的Python 3.7.3上,我正在执行以下操作:
import sys
if not sys.stdout.isatty():
sys.stdout.reconfigure(encoding='utf-8')
print("Mamma mia.")
当作为encodingtest.py > test.txt
运行时,test.txt
结果是:
00000000 FF FE 4D 00 61 00 6D 00 6D 00 61 00 20 00 6D 00 ÿþM.a.m.m.a. .m.
00000010 69 00 61 00 2E 00 0D 00 0A 00 i.a.......
奇怪的是,它以FF FE
开始,这是UTF-16-LE的字节顺序标记–字符之间打印空字节(正如UTF-16所示)!然而,当我通过CMD而不是PowerShell运行它时,它可以很好地打印UTF-8即使通过PowerShell管道传输,如何让Python打印UTF-8?
我可以改为运行encodingtest.py | Out-File -Encoding UTF8 test.txt
,但是有没有办法确保输出编码程序端?
PowerShell基本上不支持处理来自外部程序的原始输出(一个字节流):
它总是使用存储在
[Console]::OutputEncoding
中的字符编码对输出进行解码,例如文本解码后,它将其默认字符编码用于文件输出操作,例如} cmdlet的别名),对于
>
(实际上是^{>
来说,它是:换言之:即使仅使用
>
也需要一个字符解码和重新编码周期,原始编码和结果编码之间没有任何关系。因此:
(暂时)设置
[Console]::OutputEncoding = [System.Text.UTF8Encoding]::new()
将Python脚本调用的输出通过管道传输到} 和
Out-File
,或者最好是,如果已知输入已经是字符串(对于外部程序调用始终为true)^{Encoding utf8
-Encoding utf8BOM
创建一个李>要将其放在一起(保存和恢复未显示的原始
[Console]::OutputEncoding
):如this answer中所述,如果您已切换到UTF-8系统范围的,则无需修改
[Console]::OutputEncoding
,但请注意,此Windows 10功能在撰写本文时仍处于测试阶段,具有深远的影响或者,通过的文件:
cmd.exe
调用,这会将原始字节传递给具有^{这种技术(类似于通过
/bin/sh -c
应用于类Unix平台)是解决缺少原始字节处理的一般方法(见下文)背景信息:PowerShell管道中缺少对原始字节流的支持:
PowerShell的管道基于对象,这意味着流经它的是.NET类型的实例。这种传统的、仅二进制的管道的演变是PowerShell强大功能和多功能性的关键
PowerShell中的一切都是通过管道进行调解的,包括使用重定向操作符
>
,其中... > foo.txt
实际上是... | Out-File foo.txt
的语法糖对于总是输出.NET对象的PowerShell本机命令,需要某种形式的编码,以便以有意义的方式将这些对象写入文件(除非对象已经是字符串,否则原始字节表示没有任何意义),因此,使用了基于PowerShell的显示输出格式化系统的文本表示(顺便说一句,这就是为什么带有非字符串输入的
>
通常不适合生成用于以后编程处理的文件的原因)对于外部程序,PowerShell选择仅通过文本(字符串)与它们通信,在接收输出时,不可避免地将接收到的原始字节解码为.NET字符串,如上所述
有关更多信息,请参见this answer
缺少对原始字节流的支持是有问题的: 除非您直接调用底层的.NET API来显式处理字节流(这将非常麻烦),否则解码和重新编码为文本的循环:
能改变数据,不仅干扰sending字节流到文件,但也带有管道数据在/到外部程序之间;有关示例,请参见this answer
会显著降低性能
从历史上看,当PowerShell是一个只支持Windows的shell时,这并不是什么大问题,因为Windows世界没有太多可调用的CLI(命令行界面(实用程序)),因此留在PowerShell的范围内通常就足够了(尽管存在性能问题)
然而,在一个越来越跨平台的世界中,尤其是在类Unix平台上,有能力的CLI比比皆是,有时对于高性能的操作来说是必不可少的
因此,PowerShell应至少支持原始字节流随需应变,并且在检测到数据在两个外部程序之间通过管道传输时,甚至可以自动。见GitHub issue #1908和GitHub issue #5974
相关问题 更多 >
编程相关推荐