Как сообщить Python, что sys.argv находится в Unicode?
Вот небольшая программа:
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? В противном случае, как преобразовать ASCII (который имеет unicode внутри него) в Unicode? Очевидные преобразования не работают.
Ответы
Ответ 1
Ошибка UnicodeDecodeError
, которую вы видите, связана с тем, что вы смешиваете строку Unicode u"f=%s"
и sys.argv[1]
bytestring:
-
оба байта:
$ python -c'import sys; print "f=%s" % (sys.argv[1],)' 'Recent/רשימת משתתפים'
Это пропускает байты прозрачно с/на ваш терминал. Он работает для любой кодировки.
-
Оба Unicode:
$ python -c'import sys; print u"f=%s" % (sys.argv[1].decode("utf-8"),)' 'Rec..
Здесь вы должны заменить 'utf-8'
на кодировку, используемую вашим терминалом. Вы можете использовать sys.getfilesystemencoding()
здесь, если терминал не поддерживает Unicode.
Обе команды производят один и тот же вывод:
f=Recent/רשימת משתתפים
В общем, вы должны как можно скорее преобразовать bytestrings, которые считаете текстом в Unicode.
Ответ 2
sys.argv = map(lambda arg: arg.decode(sys.stdout.encoding), sys.argv)
или вы можете выбрать кодировку из locale.getdefaultlocale()[1]
Ответ 3
Параметры командной строки передаются в Python в виде строки байта, используя кодировку, используемую в оболочке, используемой для запущенного Python. Таким образом, нет возможности передать параметры командной строки в Python как строку юникода, отличную от того, чтобы самостоятельно преобразовывать параметры в юникод внутри вашего приложения.
Ответ 4
Ответ 5
попробуйте либо:
f = sys.argv[1].decode('utf-8')
или
f = unicode(sys.argv[1], 'utf-8')