Преобразование объектов Unicode с не-ASCII-символами в них в объекты строк (в Python)

Я хочу отправить китайские иероглифы для перевода онлайн-службой и вернуть полученную английскую строку. Я использую простой JSON и urllib для этого.

И да, я объявляю.

# -*- coding: utf-8 -*-

поверх моего кода.

Теперь все работает нормально, если я передаю urllib объект типа строки, даже если этот объект содержит информацию о Unicode. Моя функция называется translate.

Например:

stringtest1 = '無與倫比的美麗'

print translate(stringtest1)

приводит к правильному переводу и делает

type(stringtest1) 

подтверждает это как строковый объект.

Но если do

stringtest1 = u'無與倫比的美麗'

и попытайтесь использовать мою функцию перевода. Я получаю эту ошибку:

  File "C:\Python27\lib\urllib.py", line 1275, in urlencode
    v = quote_plus(str(v))
UnicodeEncodeError: 'ascii' codec can't encode characters in position 2-8: ordinal not in range(128)

После небольшого исследования кажется, что это обычная проблема:

Теперь, если я наберу script

stringtest1 = '無與倫比的美麗' 
stringtest2 = u'無與倫比的美麗'
print 'stringtest1',stringtest1
print 'stringtest2',stringtest2

извещение о его возврате:

stringtest1 無與倫æ¯"的美麗
stringtest2 無與倫比的美麗

Но просто введите переменные в консоли:

>>> stringtest1
'\xe7\x84\xa1\xe8\x88\x87\xe5\x80\xab\xe6\xaf\x94\xe7\x9a\x84\xe7\xbe\x8e\xe9\xba\x97'
>>> stringtest2
u'\u7121\u8207\u502b\u6bd4\u7684\u7f8e\u9e97'

получает это.

Моя проблема заключается в том, что я не контролирую, как передаваемая информация подходит к моей функции. И мне кажется, что я должен привести его в форму Unicode, которая не принимается функцией.

Итак, как мне преобразовать одну вещь в другую?

Я прочитал вопрос о переполнении стека Преобразовать Юникод в строку в Python (содержащий дополнительные символы).

Но это не то, что мне нужно. Urllib принимает строковый объект, но не объект Unicode, оба содержат одну и ту же информацию

Ну, по крайней мере, в глазах веб-приложения я отправляю неизмененную информацию, я не уверен, что они все еще эквивалентны в Python.

Ответ 1

Когда вы получаете объект unicode и хотите вернуть из него закодированную строку байта UTF-8, используйте theobject.encode('utf8').

Кажется странным, что вы не знаете, является ли входящий объект str или unicode - наверняка, вы также контролируете сайты вызовов этой функцией? Но если это действительно так, по какой бы то ни было странной причине вам может понадобиться что-то вроде:

def ensureutf8(s):
    if isinstance(s, unicode):
        s = s.encode('utf8')
    return s

который кодируется только условно, то есть, если он получает объект unicode, а не если объект, который он принимает, уже является байтовой строкой. Он возвращает байтовую строку в любом случае.

Кстати, часть вашего замешательства, похоже, связана с тем фактом, что вы не знаете, что просто ввод выражения в приглашении интерпретатора покажет вам его repr, что не является тем же эффектом, который вы получаете с помощью print; -.)