【发布时间】:2012-02-10 10:45:48
【问题描述】:
我以为我对编码和 Python 了如指掌,但今天我遇到了一个奇怪的问题:虽然控制台设置为代码页 850 - Python 正确报告了它 - 我放在命令行上的参数似乎被编码为代码页 1252。如果我尝试使用 sys.stdin.encoding 对其进行解码,则会得到错误的结果。如果我假设“cp1252”,忽略 sys.stdout.encoding 报告的内容,它会起作用。
我是否遗漏了什么,或者这是 Python 中的一个错误?窗户?注意:我在 Windows 7 EN 上运行 Python 2.6.6,语言环境设置为法语(瑞士)。
在下面的测试程序中,我检查了文字是否被正确解释并且可以打印 - 这很有效。但是我在命令行上传递的所有值似乎都被错误地编码了:
#!/usr/bin/python
# -*- encoding: utf-8 -*-
import sys
literal_mb = 'utf-8 literal: üèéÃÂç€ÈÚ'
literal_u = u'unicode literal: üèéÃÂç€ÈÚ'
print "Testing literals"
print literal_mb.decode('utf-8').encode(sys.stdout.encoding,'replace')
print literal_u.encode(sys.stdout.encoding,'replace')
print "Testing arguments ( stdin/out encodings:",sys.stdin.encoding,"/",sys.stdout.encoding,")"
for i in range(1,len(sys.argv)):
arg = sys.argv[i]
print "arg",i,":",arg
for ch in arg:
print " ",ch,"->",ord(ch),
if ord(ch)>=128 and sys.stdin.encoding == 'cp850':
print "<-",ch.decode('cp1252').encode(sys.stdout.encoding,'replace'),"[assuming input was actually cp1252 ]"
else:
print ""
在新创建的控制台中,运行时
C:\dev>test-encoding.py abcé€
我得到以下输出
Testing literals
utf-8 literal: üèéÃÂç?ÈÚ
unicode literal: üèéÃÂç?ÈÚ
Testing arguments ( stdin/out encodings: cp850 / cp850 )
arg 1 : abcÚÇ
a -> 97
b -> 98
c -> 99
Ú -> 233 <- é [assuming input was actually cp1252 ]
Ç -> 128 <- ? [assuming input was actually cp1252 ]
虽然我希望第 4 个字符的序数值为 130 而不是 233(请参阅代码页 850 和 1252)。
注意:欧元符号的值 128 是个谜 - 因为 cp850 没有它。否则,'?'预期 - cp850 无法打印字符,我在转换中使用了“替换”。
如果我通过发出 chcp 1252 将控制台的代码页更改为 1252 并运行相同的命令,我(正确)获得
Testing literals
utf-8 literal: üèéÃÂç€ÈÚ
unicode literal: üèéÃÂç€ÈÚ
Testing arguments ( stdin/out encodings: cp1252 / cp1252 )
arg 1 : abcé€
a -> 97
b -> 98
c -> 99
é -> 233
€ -> 128
任何想法我错过了什么?
编辑 1: 我刚刚通过阅读 sys.stdin 进行了测试。这按预期工作:在 cp850 中,键入 'é' 会导致序数值为 130。所以问题实际上只出在命令行上。那么,命令行与标准输入的处理方式不同吗?
编辑 2: 看来我的关键字有误。我在 SO 上找到了另一个非常接近的话题:Read Unicode characters from command-line arguments in Python 2.x on Windows。尽管如此,如果命令行没有像 sys.stdin 那样编码,并且由于 sys.getdefaultencoding() 报告“ascii”,似乎没有办法知道它的实际编码。我发现使用 win32 扩展的答案非常 hacky。
【问题讨论】: