如何告诉Python sys.argv是Unicode?

16 投票
5 回答
12495 浏览
提问于 2025-04-16 12:30

这里有一个小程序:

import sys

f = sys.argv[1]
print type(f)
print u"f=%s" % (f)

这是我运行这个程序的结果:

$ python x.py 'Recent/רשימת משתתפים.LNK'
<type 'str'>
Traceback (most recent call last):
  File "x.py", line 5, in <module>
    print u"f=%s" % (f)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd7 in position 7: ordinal not in range(128)
$ 

问题在于,sys.argv[1] 认为它得到的是一个 ASCII 字符串,但它无法转换成 Unicode。不过我使用的是 Mac,终端支持完整的 Unicode,所以 x.py 实际上得到了一个 Unicode 字符串。我该如何告诉 Python sys.argv[] 是 Unicode 而不是 ASCII?如果不能这样做,我该如何把包含 Unicode 的 ASCII 转换成 Unicode?一些明显的转换方法并不奏效。

5 个回答

3

命令行参数在启动Python时会以字节字符串的形式传入,这个字节字符串的编码方式是和你用来启动Python的命令行一样的。所以,除了在你的程序里自己把这些参数转换成Unicode字符串之外,没办法直接把命令行参数作为Unicode字符串传入Python。

5
sys.argv = map(lambda arg: arg.decode(sys.stdout.encoding), sys.argv)

或者你可以从 locale.getdefaultlocale()[1] 中选择编码方式。

21

你看到的 UnicodeDecodeError 错误是因为你把 Unicode 字符串 u"f=%s"sys.argv[1] 的字节串混在一起了:

  • 如果都是字节串:

      $ python2 -c'import sys; print "f=%s" % (sys.argv[1],)' 'Recent/רשימת משתתפים'
    

    这样可以在你的终端和程序之间透明地传递字节,适用于任何编码方式。

  • 如果都是 Unicode:

      $ python2 -c'import sys; print u"f=%s" % (sys.argv[1].decode("utf-8"),)' 'Rec..
    

    在这里你应该把 'utf-8' 替换成你终端使用的编码。如果你的终端不支持 Unicode,可以用 sys.getfilesystemencoding() 来获取编码。

这两条命令的输出是一样的:

f=Recent/רשימת משתתפים

一般来说,你应该尽快把你认为是文本的字节串转换成 Unicode。

撰写回答