Декодирование, если это не unicode

Я хочу, чтобы моя функция приняла аргумент, который может быть объектом unicode или строкой, кодированной utf-8. Внутри моей функции я хочу преобразовать аргумент в unicode. У меня есть что-то вроде этого:

def myfunction(text): if not isinstance(text, unicode): text = unicode(text, 'utf-8') ... 

Можно ли избежать использования isinstance? Я искал что-то более утиное.

Во время моих экспериментов с расшифровкой я столкнулся с несколькими странными поведением Python. Например:

 >>> u'hello'.decode('utf-8') u'hello' >>> u'cer\xf3n'.decode('utf-8') Traceback (most recent call last): File "<input>", line 1, in <module> File "/usr/lib/python2.6/encodings/utf_8.py", line 16, in decode return codecs.utf_8_decode(input, errors, True) UnicodeEncodeError: 'ascii' codec can't encode character u'\xf3' in po sition 3: ordinal not in range(128) 

Или

 >>> u'hello'.decode('utf-8') u'hello' 12:11 >>> unicode(u'hello', 'utf-8') Traceback (most recent call last): File "<input>", line 1, in <module> TypeError: decoding Unicode is not supported 

Кстати. Я использую Python 2.6

  • как показать китайское слово, а не юникодное слово
  • кодировка python urllib2 utf-8
  • Почему Python настаивает на использовании ascii?
  • Python - Python 3.1 не может обрабатывать кодированные файлы UTF-16?
  • Преобразование Unicode в python
  • Python DictWriter записывает CSV-файлы с кодировкой UTF-8
  • Ошибка MySQL «неправильное строковое значение» при сохранении строки unicode в Django
  • python может кодировать utf-8, но не может декодировать
  • 2 Solutions collect form web for “Декодирование, если это не unicode”

    Вы можете просто попробовать декодировать его с помощью кодека «utf-8», и если это не сработает, верните объект.

     def myfunction(text): try: text = unicode(text, 'utf-8') except TypeError: return text print(myfunction(u'cer\xf3n')) # cerón 

    Когда вы берете объект unicode и вызываете его метод decode с помощью кодека 'utf-8' , Python сначала пытается преобразовать объект unicode в строковый объект, а затем вызывает метод декодирования строкового объекта ('utf-8').

    Иногда преобразование из объекта unicode в строковый объект выходит из строя, потому что Python2 по умолчанию использует ascii-кодек.

    Поэтому, вообще, никогда не пытайтесь декодировать объекты unicode. Или, если вы должны попробовать, затащите его в блок try..except. Могут быть несколько кодеков, для которых декодирование юникодовых объектов работает в Python2 (см. Ниже), но они были удалены в Python3.

    Посмотрите этот билет на ошибку Python для интересного обсуждения этой проблемы, а также блог Guido van Rossum :

    «Мы применяем несколько иной подход к кодекам: в то время как в Python 2 кодеки могут принимать либо Unicode, либо 8- битные данные в качестве входных данных и производить либо в качестве вывода, в Py3k, кодирование всегда является переводом из строки Unicode (text) массив байтов и декодирование всегда идет в противоположном направлении. Это означает, что нам пришлось отказаться от нескольких кодеков, которые не подходят в этой модели, например rot13, base64 и bz2 (эти преобразования все еще поддерживаются, а не через кодировку / decode API). "

    Я не знаю, какой хороший способ избежать проверки isinstance в вашей функции, но, возможно, кто-то еще будет. Я могу указать, что две странности, которые вы цитируете, – это потому, что вы делаете что-то, что не имеет смысла: пытаться декодировать в Unicode что-то, что уже декодировано в Unicode.

    Первый должен выглядеть таким образом, который декодирует кодировку UTF-8 этой строки в версию Unicode:

     >>> 'cer\xc3\xb3n'.decode('utf-8') u'cer\xf3n' 

    И ваша вторая должна выглядеть так (не используя строковый литерал u'' Unicode):

     >>> unicode('hello', 'utf-8') u'hello' 
    Python - лучший язык программирования в мире.