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