Я хотел к URL, кодируют строку Python и получил исключения с еврейскими строками. Я не мог зафиксировать его и начал делать, некоторое предположение ориентировало программирование. Наконец, выполнение mystr = mystr.encode("utf8")
прежде, чем отправить его на кодер URL спасено положение.
Кто-то может объяснить, что произошло? Что делает .encode ("utf8"), делают? Моя исходная строка была строкой unicode так или иначе (т.е. снабдил префиксом u).
Исходная строка была объектом Unicode, содержащим необработанные кодовые точки Unicode , после кодирования ее как UTF-8 это обычная строка байтов, содержащая UTF-8 закодированные данные.
Кодировщик URL-адресов, похоже, ожидает байтовую строку, поэтому он может кодировать URL-адрес один за другим байты и не иметь дело с точками кода Unicode. Когда вы даете ему объект Unicode, он пытается преобразовать его в байтовую строку, используя некоторую кодировку по умолчанию, возможно, ASCII. Для символов иврита, которые нельзя представить как ASCII, это приведет к ошибкам.
Моя исходная строка в любом случае была строкой в Юникоде (т.е. с префиксом u)
... что является проблемой. Это была не «строка» как таковая, а «объект Unicode». Он содержит последовательность кодовых точек Unicode. Эти кодовые точки, конечно, должны иметь какое-то внутреннее представление, о котором знает Python, но все, что оно есть, абстрагируется, и они отображаются как эти \ uXXXX
сущности, когда вы печатаете repr (my_u_str)
.
Чтобы получить последовательность байтов, которую может понять другая программа, вам нужно взять эту последовательность кодовых точек Unicode и закодировать ее. С кодировкой нужно определиться, ведь есть из чего выбирать. Обычно используются UTF8 и UTF16. ASCII тоже может быть, если подходит. u "abc" .encode ('ascii')
работает нормально.
Выполните my_u_str = u "\ u2119ython"
, а затем введите (my_u_str)
и тип (my_u_str.encode ('utf8'))
, чтобы увидеть разница в типах: первый -
, а второй -
. (Во всяком случае, под Python 2.5 и 2.6).
В Python 3 все по-другому, но, поскольку я редко использую его, я бы сказал не на шутку, если бы попытался сказать что-нибудь авторитетное об этом.
Он возвращает кодированную в UTF-8 версию строки Unicode, mystr. Важно понимать, что UTF-8 - это просто один из способов кодирования Юникода. Python может работать со многими другими кодировками (например, mystr.encode("utf32") или даже mystr.encode("ascii")).
В ссылке, которую разместил balpha, все объясняется. Вкратце:
Тот факт, что ваша строка имеет префикс "u", означает, что она состоит из символов Юникода (или кодовых точек). UTF-8 - это кодирование этой строки в последовательность байт.
"...".encode("utf-8") преобразует представление строки в памяти в UTF-8 -кодированную строку.
url-кодер, вероятно, ожидал получить байтстринг, то есть строковое представление, где каждый символ представлен одним байтом.
Что делает .encode ("utf8")?
Это зависит от того, какую версию Python вы используете:
str
( в кодировке UTF-16 или UTF-32) в объект байтов
, содержащий представление строки в формате UTF-8. unicode
в объект str
, закодированный в UTF-8. Но str
также имеет метод encode
, и запись '...'. Encode ('UTF-8')
эквивалентна записи ' ... '. decode (' ascii '). encode (' UTF-8 ')
. Поскольку вы упомянули префикс «u», вы должны использовать 2.x. Если вам не требуются какие-либо библиотеки только для 2.x, я бы рекомендовал перейти на 3.x, в котором есть четкое различие между текстовыми и двоичными данными.
Погружение в Python 3 дает хорошее объяснение проблемы.
Может кто-нибудь объяснить, что произошло?
Было бы полезно, если бы вы сказали нам, в чем было сообщение об ошибке.
Функция urllib.quote
ожидает объект str
. Также случается работать с объектами unicode
, которые содержат только символы ASCII, но не содержат буквы иврита.
В Python 3.x urllib.parse.quote
принимает как str
(= Python 2.x unicode
), так и байты
] объекты. Строки автоматически кодируются в UTF-8.