Python subprocess.check_output 处理±字符

2 投票
2 回答
2176 浏览
提问于 2025-04-17 08:21

我正在使用一个叫做 subprocess.check_output 的方法来调用一个 MS DOS 命令行程序,目的是获取这个程序返回的 stdout 字符串。

这个方法返回的信息包括刚刚执行的命令的相关信息,还有一行新行,里面是我想要的结果,最后又是一行新行。具体返回的字符串看起来是这样的:

b'0ms: Channel.#0.Range.SelectedItem?\r\n\xf150 mV\r\n'

问题在于第一个新行后面的 \xf1 这个字符,它本来应该是一个 ±(也就是 \xb1),但总是返回成 ñ(\xf1),我搞不清楚为什么会这样。

如果我在命令行手动运行这个命令,我能得到我预期的 ±,所以我觉得这个命令行程序没有问题。

短期内我可以把找到的 \xf1 替换成 \xb1,但这只是个临时解决办法,我更希望能找到根本原因,而不是绕过它。

有没有人知道为什么在命令行和 Python 中字符会有差异呢?

2 个回答

1

你运行的程序可能使用了和你在 Python 脚本中设置的编码不同的编码。如果我没猜错的话,你可以找出它使用的编码,然后用 .decode(<原始编码>).encode(<目标编码>) 方法来解决这个问题。

补充:我似乎找到了一个可能的编码:

>>> print s.decode('cp850')
0ms: Channel.#0.Range.SelectedItem?
±50 mV

请注意,这并不能保证它适用于所有可能的输出,只是说它可能是正确的,并且对 ± 这个字符有效...

补充2:当我在研究编码的时候,jsbueno 也得出了同样的结论,但他从“历史的角度”分析了为什么这个编码可能是你需要使用的...

希望这对你有帮助!

2

MS DOS应用程序使用的字符编码和Windows的拉丁编码(cp1252)或者现代世界常用的编码(网页和Unix系统用的utf-8)是不一样的。为了兼容老旧系统,它们使用的是CP850编码。

要想从这个字符串中得到正确的Python Unicode,只需要用CP850编码来解码它,像这样:

>>> print '0ms: Channel.#0.Range.SelectedItem?\r\n\xf150 mV\r\n'.decode("cp850")
0ms: Channel.#0.Range.SelectedItem?
±50 mV

撰写回答