2017-02-20 18 views
1

В Python интерактивном режиме:python2.7 выполняет операторы, заданные в виде строки команды решительность Unicode неправильно, но интерактивные подсказки делает хорошо

Python 2.7.12 (default, Nov 19 2016, 06:48:10) 
[GCC 5.4.0 20160609] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> s = u'中' 
>>> s 
u'\u4e2d' 
>>> print s 
中 

я могу получить строку Unicode «中» печатается правильно.
Но когда я, как это в командной строке Bash:
python2 -c "s = u'中'; print(repr(s)); print(s)"
результат команды я получаю

u'\xe4\xb8\xad' 
中 

Мой терминал набор символов кодировка «UTF-8». Итак, что не так с операциями командной строки Python? Почему операторы командной строки не могут правильно печатать строку Unicode?

Спасибо!

ответ

1

Это интересный вопрос. Я пытаюсь вникать и заключить, что это проблема того, как параметр командной строки -c переведен в исходный код в интерпретаторе Python 2.

Кажется, что в Python 2 s = u'中' в параметре командной строки (оболочки Unicode) переведено как s = u'\xe4\xb8\xad'. Как будто он запускает файл сценария с кодировкой latin1 (такой расширенный ASCII). Хотя в Python 3 он переводится как s = u'\u4e2d', поэтому он печатает правильно. Итак, это не проблема bash или терминала.

 
Interpreting source as utf-8: 
    [73] [20] [3d] [20] [75] [27] [e4 b8 ad] [27] 
    [s] [ ] [=] [ ] [u] ['] [中]  ['] 

Interpreting source as latin-1: 
    [73] [20] [3d] [20] [75] [27] [e4] [b8] [ad] [27] 
    [s] [ ] [=] [ ] [u] ['] [ä] [¸] [­] ['] 

Попробуйте python2 консоль:

>>> s = u'\xe4\xb8\xad' 
>>> s 
u'\xe4\xb8\xad' 
>>> print s 
中 

>>> print u'\xe4' 
ä 
>>> print u'\xb8' 
¸ 
>>> print u'\xad' 
­ 

Как я уже говорил, это как если бы вы написать исходный код, сформулируем его в latin1 закодированной, и работать с python2. Попробуйте сохранить этот код в файл и работать с python2:

# coding=latin1 
s = u'中' 
print repr(s) 
print s 

Выход:

u'\xe4\xb8\xad' 
中 

Это мой вывод, это проблема того, как параметр командной строки из -c является «декодируется» в качестве источника в Python 2, как если бы он был декодирован с использованием latin1.

Так, хак для этого:

echo -e "# coding=utf8\ns = u'中'; print(repr(s)); print(s)" | python 

Больше чтения

1

Юникодные символы, которые вы вводите в bash, передаются как UTF-8.

Это означает, что ввод это в Баше:

python2 -c "s = u'中'; print(repr(s)); print(s)" 

получает работать как этот код:

s = u'\xe4\xb8\xad'; 
print(repr(s)); 
print(s) 

u'something»является Юникод буквального, который не делает UTF-8 декодирования, но интерпретирует байты как символы напрямую. u '\ xe4 \ xb8 \ xad' понимается как строка из трех символов: E4, B8 и AD (ä, "cedilla" и "soft hyphen").

Причина, по которой он работает из интерактивного приглашения, заключается в том, что при вводе s = u '中' интерпретатор передает его непосредственно как u '\ u4e2d' без использования UTF-8.

+1

Да, это работает, но я хочу знать, почему результат отличается, а операторы командной строки не могут дать правильный результат? – zhenguoli

+0

Интересно, что python -c "s = u '\ u4e2d'; print repr (s); print s" также работает, интересно, что проблема с s = u '中' ... – Bemmu

+0

\ xe4 \ xb8 \ xad является кодировкой UTF-8 中, поэтому он выглядит как bash уже utf-8, кодирующий его – Bemmu