Python:用于处理sys.argv的编码是什么?

24
在Python中,sys.argv元素使用什么编码方式进行编码?它们是否使用sys.getdefaultencoding()编码方式进行编码?

sys.getdefaultencoding():返回Unicode实现所使用的当前默认字符串编码名称。

PS:正如一些答案所指出的那样,sys.stdin.encoding可能是一个更好的猜测。我希望看到这个问题的明确答案,并提供有关可靠来源的指针! PPS:正如Wim指出的那样,Python 3通过将str对象放入sys.argv(如果我理解正确)来解决了这个问题。然而,在Python 2.x中,这个问题仍然存在。在Unix下,LC_CTYPE环境变量似乎是正确的检查对象,对吗?在Windows中应该怎么做(以便无论控制台是什么样子,sys.argv元素都能被正确地解释)?
7个回答

8

我猜你问这个问题是因为你遇到了2128号问题。请注意,这在Python 3.0中已被修复。


1
谢谢,我会检查链接。实际上,我是在预防性地提问,在编写从命令行获取用户消息的程序之前。 - Eric O. Lebigot
Python 2.x怎么办?还有Windows系统呢? - Eric O. Lebigot

6

以下是几点观察:

(1) 它肯定不是sys.getdefaultencoding

(2) sys.stdin.encoding似乎是更好的选择。

(3) 在Windows上,实际的sys.stdin.encoding值会有所不同,这取决于提供stdio的软件。IDLE将使用系统"ANSI"代码页,例如在大部分西欧、美国和前殖民地中的cp1252。然而,在模拟MS-DOS的命令提示符窗口中,相应的旧DOS代码页(例如cp850)将被默认使用。可以使用CHCP(更改代码页)命令来更改此设置。

(4) 子进程模块的文档没有提供关于args和stdout要使用哪种编码的建议。

(5) 人们相信assert sys.stdin.encoding == sys.stdout.encoding永远不会失败。


这些观察似乎是正确的,我也观察到了同样的情况。你有没有关于sys.getdefaultencoding返回的具体信息的想法? - Ankit Jaiswal
它返回Unicode实现所使用的当前默认字符串编码的名称。我认为这意味着Python在其控制台中使用defaultencoding()。顺便说一下,您可以通过在前面添加u'来覆盖defaultencoding()。非常好的答案+1。 - soulseekah
4
我同意关于(2)的观点——这是我后来想到的。(5)实际上是不正确的:在Unix下,“python test.py >test.txt”可以例如将UTF-8用作stdin编码,而将None用作stdout编码。 - Eric O. Lebigot

5

我不知道这是否有帮助,但这是我在DOS模式下得到的:

C:\Python27>python Lib\codingtest.py нер
['Lib\\codingtest.py', '\xed\xe5\xf0']

C:\Python27>python Lib\codingtest.py hello
['Lib\\codingtest.py', 'hello']

在IDLE中:
>>> print "hello"
hello
>>> "hello"
'hello'
>>> "привет"
'\xef\xf0\xe8\xe2\xe5\xf2'
>>> print "привет"
привет
>>> sys.getdefaultencoding()
'ascii'
>>> 

从这个中我们能得出什么结论呢?我还不知道...稍后我会评论一下。

稍后一点sys.argv使用的编码是sys.stdin.encoding而不是sys.getdefaultencoding()


\xef 是SMALL LETTER PE('п')的UNICODE CP1251 Cyrillic表示,因此我开始相信sys.argv是使用sys.stdin.encoding而非sys.getdefaultencoding()进行编码的。 - soulseekah

4

"应该如何处理Windows(以便sys.argv元素在任何控制台下都能被正确解释)?"

对于Python 2.x,请参见这个问题2128的评论

(请注意,原始的sys.argv没有正确的编码,因为某些字符可能已经以无法撤销的方式损坏;例如,如果ANSI代码页无法表示希腊字母alpha,则会将其损坏为'a'。)


标记为已接受:这个关于问题2128的新评论是新信息!谢谢! - Eric O. Lebigot

4
在Unix系统中,它应该在用户的语言环境中,这与sys.getdefaultencoding不相关(奇怪的是)。请参见http://docs.python.org/library/locale.html
在Windows中,它将使用系统ANSI代码页。
(顺便说一句,那些告诉你不要以介词结尾的小学老师是在骗你。)

我不会容忍悬挂介词这种事情。对于悬挂介词的所谓限制显然是从风格观察中演变而来的。换句话说,一个句子的首尾词汇对于产生最自然的影响力。因此,将仅仅一个介词放置在如此战略重要的位置被认为是风格上的弱点。 - Jim Dennis
@Jim:风格固然重要,但有些人似乎有这种愚蠢的观念,认为它不符合语法规则,导致出现了这个问题的标题这样的荒谬情况。 - Glenn Maynard
这个问题的标题似乎已经足够清晰,尽管我可能会建议使用“which”而不是“what”。更精确的措辞可能是:“用于处理sys.argv的编码是哪个?”整个文本编码问题已经变得非常复杂,因为所有这些尝试都要同时容纳国际字符集,同时保留一些简单的ASCII字符串处理。围绕整个事件的术语也变得非常复杂。 - Jim Dennis
@Jim:这个观点只是一个有趣的旁白,自然地写出这句话是完全没有问题的:“sys.argv使用的编码是什么?”“使用什么编码”并不是不清楚,只是有些奇怪和不自然。 - Glenn Maynard
1
供参考:我猜这个答案是指 locale.getdfaultlocale()[1](https://docs.python.org/2/library/locale.html#locale.getdefaultlocale)。 - Eric O. Lebigot

1

0

对我来说,sys.getfilesystemencoding()是有效的,至少在Windows上是这样。 在Windows上它实际上是'mbcs',而在*nix上则是'utf-8'。


问题是,Windows有两个正确的代码页。对于GUI程序来说,使用GetACP(),而对于文本程序来说,使用GetOENCP()。对于许多语言来说,这两者的值是相同的,但并非所有语言都是如此... - Arioch 'The
问题是,Windows 有两个正确的代码页。对于图形界面程序,使用GetACP(),对于文本程序,使用GetOENCP()。对于许多语言,它们具有相同的值,但并非所有语言都是如此…… - undefined

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