gpt4 book ai didi

python - 如何选择使用哪种字符编码?

转载 作者:行者123 更新时间:2023-12-04 08:56:54 24 4
gpt4 key购买 nike

在 Python 中,使用 subprocess.Popen我们经常不得不将外部工具的输出从字节转换为字符串。我一直使用 UTF-8 来解决这个问题,没有考虑太多,到目前为止我还没有遇到过问题。我遇到了一些有人使用 ASCII 代替的代码,这让我想到我应该如何知道要使用哪种编码,这有关系吗?
对于简单的字符串,它似乎没有什么区别,例如:

>>> subprocess.check_output(['git', 'rev-parse', '--short', 'HEAD'], encoding='ASCII')
'4091146\n'
>>> subprocess.check_output(['git', 'rev-parse', '--short', 'HEAD'], encoding='utf-8')
'4091146\n'
我知道 UTF-8 是一个更大的字符集,因此“特殊”字符不能编码为 ASCII:
>>> "Büster".encode('utf-8')
b'B\xc3\xbcster'
>>> "Büster".encode('ascii')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character '\xfc' in position 1: ordinal not in range(128)
我猜编码取决于外部程序,所以我怎么知道要使用哪一个?总是假设 UTF-8 是否安全?

最佳答案

没有“一刀切”的答案。在你的系统上有意义的东西对其他系统没有意义。 (如果不是这种情况,Python 应该只支持一种编码,你不觉得吗?)
在任何计算机上,主要考虑因素是与系统上的其他实用程序保持兼容。如果您的系统是来自黑暗时代的“大铁”大型机,那么可能所有东西都需要配置为使用一些可怕的传统 8 位编码(或更糟!)在光谱的另一端,世界正在朝着 Unicode 和特别是 UTF-8 编码(另见 https://utf8everywhere.org/ );如果您使用的是相当现代的非 Windows 系统,那么您的 locale 可能表明该系统已设置为 UTF-8,然后这就是您应该使用的(并且几乎可以肯定 Python 已经配置为用作其默认编码; 所以你真的只需要说 text=True 而不是明确命名编码)。
剩下的就是 Windows,它通常配置有任何代码页对其销售的地理位置有意义;在美洲和西欧,这意味着代码页 1252,而在世界其他地区,它意味着其他东西(东欧 1250 或 1251,世界其他地区的各种其他国家或地区特定的代码页);但同样,使用 subprocess 您可以只使用 text=True 并让 Python 代表您选择。
关键字参数 text=True 以前称为 universal_newlines=True 仍然有效;真正旧的 Python 3 版本仍然需要您显式编码和解码,当然在某些情况下您需要或想要使用原始二进制编码与选定的外部实用程序进行通信。
例子:

r = subprocess.run(['git', 'rev-parse', '--short', 'HEAD'],
text=True, capture_output=True)
print(r.stdout) # implicitly uses Python's default encoding to decode

s = subprocess.run(['dd', 'if=/dev/urandom', 'bs=32', 'count=1'],
capture_output=True)
random_bytes = s.stdout # not text, no encoding, just raw bytes

# Actually don't use Popen when run() can do the job
fugly = subprocess.Popen(['cat', '/etc/motd'], text=True)
stdout, stderr = fugly.communicate()
fugly.wait() # really, use subprocess.run() instead

# If you specifically want a particular encoding, of course, go for it
weird = subprocess.run(['iconv', '-t', 'koi8-u'],
stdin=open('utf8.txt'), encoding='koi8-u', capture_output=True)
( subprocess.run() 替换了 check_output 和 friend 们,尽管您当然仍然可以为了方便使用它们。无论如何,这些示例中的大多数都确实受到了折磨,您应该真正使用 Python 的 native 功能而不是外部子进程。)
在正在迁移的系统上,您确实必须单独检查每个实用程序所需的编码,尽管对于 UTF-8 它是方便透明的,而且许多从未明确适应 UTF-8 的实用程序将继续去工作。问题区域将是排序规则(排序顺序)和 Unicode 规范化等极端情况(天真的字符串比较不会将序列 U+006F U+0308 视为等同于代码点 U+00F6,即使它们都表示单个字形 ö )。
通过网络进行通信可能很麻烦。对于 HTTP,ISO 8859-1(又名 Latin-1)曾一度被编为 HTML 的标准字符集,尽管它现在是 UTF-8。对于许多网络协议(protocol),它是未指定的,您只需进行试验。涉及文本信息的现代协议(protocol)应指定一种编码或一种机制,用于显式标记字符集和任何文本数据的编码; MIME header 最初是为电子邮件指定的,但已用于其他几种协议(protocol),包括 HTTP。电子邮件具有一系列令人困惑的附加编码,以使过去仅支持 7 位 ASCII 的 channel 完全透明;请注意 MIME header 中的邮件正文、邮件 header 和文件名属性是如何各自拥有自己的机制的。 (RFC 2045、2047 和 2231。)

关于python - 如何选择使用哪种字符编码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63771125/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com