我怎么告诉Python sys.argv是用Unicode的?

vy3*_*y32 14 python unicode macos terminal

这是一个小程序:

import sys

f = sys.argv[1]
print type(f)
print u"f=%s" % (f)
Run Code Online (Sandbox Code Playgroud)

这是我运行的程序:

$ 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)
$ 
Run Code Online (Sandbox Code Playgroud)

问题是sys.argv [1]认为它正在获得一个ascii字符串,它无法转换为Unicode.但我正在使用带有完全支持Unicode的终端的Mac,因此x.py实际上是获得了一个Unicode字符串.我怎么告诉Python sys.argv []是Unicode而不是Ascii?如果失败了,我如何将ASCII(其中包含unicode)转换为Unicode?明显的转换不起作用.

jfs*_*jfs 19

UnicodeDecodeError您看到的错误是由于您混合了Unicode字符串u"f=%s"sys.argv[1]bytestring:

  • 两个字节串:

    $ python -c'import sys; print "f=%s" % (sys.argv[1],)' 'Recent/????? ???????'
    
    Run Code Online (Sandbox Code Playgroud)

    这会从/向您的终端透明地传递字节.它适用于任何编码.

  • 两个Unicode:

    $ python -c'import sys; print u"f=%s" % (sys.argv[1].decode("utf-8"),)' 'Rec..
    
    Run Code Online (Sandbox Code Playgroud)

    在这里,您应该替换'utf-8'您的终端使用的编码.sys.getfilesystemencoding()如果终端不支持Unicode,则可以在此处使用.

两个命令都产生相同的输出:

f=Recent/????? ???????
Run Code Online (Sandbox Code Playgroud)

通常,您应该尽快将您认为是文本的字节串转换为Unicode.

  • @ vy32:`'utf-8'`是一个字符编码.它在任何上下文中都不是*Unicode.`.encode()`方法可以将Unicode字符串(文本)转换为bytestring(数据).你对Unicode是什么有一些误解.请阅读http://www.joelonsoftware.com/articles/Unicode.html (5认同)

she*_*pya 5

sys.argv = map(lambda arg: arg.decode(sys.stdout.encoding), sys.argv)
Run Code Online (Sandbox Code Playgroud)

或者您可以从中选择编码 locale.getdefaultlocale()[1]