Вы смешиваете юникод и str объекты.
Пояснение:
В Python 2.x есть два вида объектов, которые могут содержать текстовые строки. ул и юникод. str - это строка байтов, поэтому она может содержать только символы от 0 до 255.
Юникод - это строка символов Юникода.
Вы можете конвертировать между str и unicode с помощью методов «encode» и «decode»:
>>> "thisisastring".decode('ascii')
u'thisisastring'
>>> u"This is ä string".encode('utf8')
'This is \xc3\xa4 string'
Обратите внимание на кодировки. Кодировки - это способы представления текста Unicode в виде только строк байтов.
Если вы попытаетесь добавить str и unicode вместе, Python попытается преобразовать одно в другое. Но по умолчанию он будет использовать ASCII в качестве кодировки, что означает a-z, A-Z и некоторые дополнительные символы, такие как !"#$%&/()=?'{[]]}
и т. Д. В противном случае произойдет сбой.
В этот момент вы получите либо ошибку кодирования, либо ошибку декодирования, в зависимости от того, попытается ли Python преобразовать юникод в str или str в юникод. Обычно он пытается декодировать, то есть конвертировать в юникод. Но иногда он решает не принуждать, а натягивать. Я не совсем уверен, почему.
Обновление:
Причина, по которой вы получаете ошибку кодирования, а не ошибку декодирования, указанную выше, заключается в том, что message
в приведенном выше коде не является ни str, ни unicode. Это еще один объект, у которого есть метод str . Поэтому Python перед отправкой отправляет str (message), и это не удается, поскольку внутренне хранимое сообщение является объектом Unicode, который не может быть приведен к ascii.
Или, проще говоря: он не работает, так как warnings.warn () не принимает сообщения Unicode.
Теперь решение:
Не смешивайте str и unicode. Если вам нужно использовать Unicode, и вы, очевидно, делаете, постарайтесь, чтобы все строки были Unicode все время. Это единственный способ убедиться, что вы избежите этого. Это означает, что всякий раз, когда вы читаете строку с диска или вызываете функцию, которая может возвратить что-либо, кроме чистой ascii str, декодируйте ее как можно быстрее в unicode.
А когда вам нужно сохранить его на диск или отправить по сети или передать его методу, который не понимает Unicode, закодируйте его в str как можно позже.
В данном конкретном случае проблема заключается в том, что вы передаете unicode в warnings.warn (), и вы не можете этого сделать. Передайте строку. Если вы не знаете, что это такое (как, кажется, имеет место здесь), потому что это происходит откуда-то еще, ваши решения try / кроме с repr работают нормально, хотя было бы возможным выполнить кодирование.