Python: что исправляет «...». Encode («utf8»)? - PullRequest
9 голосов
/ 20 июля 2010

Я хотел URL кодировать строку Python и получил исключения со строками на иврите. Я не мог это исправить и начал заниматься программированием, ориентированным на догадки. Наконец, выполнение mystr = mystr.encode("utf8") перед отправкой в ​​кодировщик URL спасло день.

Может кто-нибудь объяснить, что случилось? Что делает .encode ("utf8")? Моя исходная строка в любом случае была строкой Unicode (то есть с префиксом u).

Ответы [ 6 ]

13 голосов
/ 20 июля 2010

Моя исходная строка в любом случае была строкой Unicode (то есть с префиксом au)

... что является проблемой.Это была не «строка» как таковая, а «объект Unicode».Он содержит последовательность кодовых точек Unicode.Эти кодовые точки должны, конечно, иметь некоторое внутреннее представление, о котором знает Python, но что бы это ни было абстрагировано, они отображаются как \uXXXX сущности, когда вы print repr(my_u_str).

Чтобы получитьпоследовательность байтов, которую может понять другая программа, вам нужно взять эту последовательность кодовых точек Unicode и кодировать ее.Вам нужно определиться с кодировкой, потому что есть из чего выбирать.UTF8 и UTF16 являются распространенным выбором.ASCII тоже может быть, если подходит.u"abc".encode('ascii') работает просто отлично.

Выполните my_u_str = u"\u2119ython", а затем type(my_u_str) и type(my_u_str.encode('utf8')), чтобы увидеть разницу в типах: первый - <type 'unicode'>, а второй - <type 'str'>.(В любом случае под Python 2.5 и 2.6).

В Python 3 все по-другому, но, поскольку я редко использую его, я бы говорил из своей головы, если бы попытался сказать что-нибудь авторитетное об этом.

9 голосов
/ 20 июля 2010

Ваша исходная строка была объектом Unicode, содержащим необработанные Unicode кодовые точки, после кодирования ее как UTF-8 это обычная строка байтов, которая содержит UTF-8 кодированные данные.1005 *

Кажется, что кодировщик URL ожидает байтовую строку, так что он может кодировать URL один байт за другим и не должен иметь дело с кодовыми точками Unicode.Когда вы даете ему объект Unicode, он пытается преобразовать его в байтовую строку, используя некоторую кодировку по умолчанию, возможно, ASCII.Для символов иврита, которые не могут быть представлены как ASCII, это приведет к ошибкам.

4 голосов
/ 31 июля 2010

Что делает .encode ("utf8")?

Зависит от того, какую версию Python вы используете:

  • В Python 3.x он преобразует объект str (закодированный в UTF-16 или UTF-32) в объект bytes, содержащий представление строки в UTF-8.
  • В Python 2.x онпреобразует объект unicode в объект str, закодированный в UTF-8.Но str также имеет метод encode, и запись '...'.encode('UTF-8') эквивалентна записи '...'.decode('ascii').encode('UTF-8').

Поскольку вы упомянули префикс "u", вы должны использовать 2.x,Если вам не нужны библиотеки только для 2.x, я бы порекомендовал перейти на 3.x, в котором есть четкое различие между текстовыми и двоичными данными.

Погружение в Python 3 *У 1024 * есть хорошее объяснение проблемы.

Может кто-нибудь объяснить, что произошло?

Было бы полезно, если бы вы сказали нам, что было сообщение об ошибке.

Функция urllib.quote ожидает объект str.Также бывает, что он работает с unicode объектами, которые содержат только символы ASCII, но не тогда, когда они содержат буквы иврита.

В Python 3.x urllib.parse.quote принимает оба str (= Python 2.xunicode) и bytes объекты.Строки автоматически кодируются в UTF-8.

1 голос
/ 20 июля 2010

"...". Encode ("utf-8") преобразует представление строки в памяти в строку, кодированную в UTF-8.

url-кодировщик, вероятно, ожидал байтовую строку, то есть строковое представление, где каждый символ представлен одним байтом.

0 голосов
/ 20 июля 2010

Ссылка , опубликованная Бальфой, объясняет все это.Вкратце:

Тот факт, что к вашей строке был добавлен префикс "u", означает, что она состоит из Unicode символов (или кодовых точек).UTF-8 - это кодирование этой строки в последовательность байтов .

0 голосов
/ 20 июля 2010

Возвращает версию строки Unicode в кодировке UTF-8, mystr.Важно понимать, что UTF-8 - это просто 1 способ кодирования Unicode.Python может работать со многими другими кодировками (например, mystr.encode ("utf32") или даже mystr.encode ("ascii")).

...