Python Unicode в и из IDE - PullRequest
       2

Python Unicode в и из IDE

1 голос
/ 20 октября 2010

когда я запускаю свои программы из Eclipse IDE, следующий фрагмент кода работает отлично:

address_name = self.text_ctrl_address.GetValue().encode('utf-8')
self.address_list = [i for i in data if address_name.upper() in i[5].upper().encode('utf-8')]

, но при запуске того же фрагмента кода непосредственно с python я получаю "UnicodeDecodeError".

Чем отличается IDE от того, что она не попадает в эту ошибку?

ps: я кодирую обе строки в Юникоде, потому что это единственный способ проверить одну строку на другую, содержащую такие буквы, как - илиç.

Редактировать:

Извините, я должен был предоставить более подробную информацию: Этот фрагмент кода принадлежит диалогу, созданному с помощью WxPython.Функция GetValue () получает текст из виджета редактирования строки и пытается сопоставить этот фрагмент текста с базой данных.Программа работает на Windows (и из-за этого, возможно, Майкл Шопсин выше может быть прав («Win-1252 до UTF-8 - серьезная неприятность»). Я много раз читал, что всегда должен работать с юникодом, избегая кодирования, но если я не кодирую, некоторые строковые методы, кажется, работают не очень хорошо, в зависимости от символов в слове (я в Испании, поэтому много символов, не относящихся к ascii). Под прямым словом я имел в виду «двойной щелчок»подайте его самостоятельно, а не из среды IDE.

Ответы [ 2 ]

1 голос
/ 24 августа 2015

UnicodeDecodeError указывает, что ошибка происходит во время декодирования байтовой строки в Unicode.

В частности, это может произойти, если вы попытаетесь кодировать строку байтов вместо строки Юникода в Python 2:

>>> u"\N{EM DASH}".encode('utf-8').encode('utf-8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 0: ordinal not in range(128)

u"\N{EM DASH}".encode('utf-8') является байтовой строкой и вызывает .encode('utf-8'), второй раз приводит к неявному .decode(sys.getdefaultencoding()), что приводит к UnicodeDecodeError.

Чем отличается IDE от того, что она не попадает в эту ошибку?

Вероятно, он работает в IDE, потому что он меняет sys.getdefaultencoding() на utf-8, что не следует делать . Это может скрыть ошибки, как показывает ваш вопрос. В общем, это также может привести к поломке сторонних библиотек, которые не ожидают не-ascii sys.getdefaultencoding() на Python 2.

Я кодирую обе строки Юникода, потому что это единственный способ проверить одну строку на другую, содержащую буквы типа - или ç.

Вы должны использовать unicodedata.normalize() вместо :

>>> import unicodedata
>>> a, b = u'\xf1', u'n\u0303'
>>> print(a)
ñ
>>> print(b)
ñ
>>> a == unicodedata.normalize('NFC', b)
True

Примечание: код в вашем вопросе может дать удивительные результаты:

#XXX BROKEN, DON'T DO IT
...address_name.upper() in i[5].upper().encode('utf-8')...

address_name.upper() вызывает метод bytes.upper, а i[5].upper() вызывает метод unicode.upper. Первый не поддерживает Unicode и может зависеть от текущей локали, последний лучше, но для сравнения без учета регистра используйте вместо этого метод .casefold():

key = unicode_address_name.casefold()
... if key == i[5].casefold()...

В общем, если вам нужно отсортировать строки в юникоде, вы можете использовать icu.Collator. Сравните лексикографическую сортировку по умолчанию:

>>> L = [u'sandwiches', u'angel delight', u'custard', u'éclairs', u'glühwein']
>>> sorted(L)
[u'angel delight', u'custard', u'gl\xfchwein', u'sandwiches', u'\xe9clairs']

при заказе на en_GB язык:

>>> import icu # PyICU
>>> collator = icu.Collator.createInstance(icu.Locale('en_GB'))
>>> sorted(L, key=collator.getSortKey)
[u'angel delight', u'custard', u'\xe9clairs', u'gl\xfchwein', u'sandwiches']
0 голосов
/ 21 октября 2010

Я мог бы решить проблему, изменив кодировку с UTF-8 на cp1252 (Windows western europe). Очевидно, UTF-8 не может кодировать некоторые символы Windows. Спасибо Майклу Шопсину выше за понимание.

Программа работает в Windows и использует диалоговое окно WxPython, получая значения из виджета редактирования строки и сопоставляя строку с базой данных.

Спасибо всем за внимание, и я надеюсь, что этот пост может помочь людям в будущем с подобной проблемой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...