Python使用print重定向将字节写入文件

4

使用 Perl,

$ perl -e 'print "\xca"' > out

现在 $ xxd out

我们有

00000000: ca

但是使用Python,我尝试过

$ python3 -c 'print("\xca", end="")' > out
$ xxd out

我得到的是

00000000: c38a

我不确定发生了什么事情。


1
在Python中,字符串默认为Unicode编码,并以UTF-8编码。尝试使用import sys; sys.stdout.write(b'\xca') - Michael Butscher
2个回答

3
在Python中,一个str对象是一系列的Unicode码点。它如何被打印到屏幕上取决于你的sys.stdout的编码方式。这是根据你的区域设置来选择的(或者可能会受到各种环境变量的影响,但默认情况下是根据你的区域设置)。所以你的区域设置必须设置为UTF-8。这也是我的默认设置:
(py311) Juans-MBP:~ juan$ locale
LANG="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_CTYPE="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_ALL=
(py311) Juans-MBP:~ juan$ python -c "print('\xca', end='')" | xxd
00000000: c38a

然而,如果我覆盖我的语言环境并告诉它使用en_US.ISO8859-1(Latin-1),一个单字节编码,我们会得到你所期望的结果:

(py311) Juans-MBP:~ juan$ LC_ALL="en_US.ISO8859-1" python -c "print('\xca', end='')" | xxd
00000000: ca

如果你想要原始字节,解决方案就是使用原始字节。在Python源代码中实现这一点的方法是使用字节文字(或字符串文字,然后使用.encode)。我们可以使用sys.stdout.buffer中的原始缓冲区:

(py311) Juans-MBP:~ juan$ python -c "import sys; sys.stdout.buffer.write(b'\xca')" | xxd
00000000: ca

或者通过将字符串编码为字节对象:

(py311) Juans-MBP:~ juan$ python -c "import sys; sys.stdout.buffer.write('\xca'.encode('latin'))" | xxd
00000000: ca

1
在Python中,\xca 被解释为UTF-8编码中的双字节字符串,因此当一个值被写入文件时,它会自动以的形式存储两个字节到文件中。
但在Perl中,\xca 被解释为十六进制值为0xca的单字节,因此当该值被存储到文件中时,它将不进行编码。 您可以查看更多细节

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接