2017-01-10 7 views
6

я получаю сообщение об ошибке в системе производства, что я не в состоянии воспроизвести в среде разработки:Как воспроизвести UnicodeEncodeError?

with io.open(file_name, 'wt') as fd: 
    fd.write(data) 

Исключение:

File "/home/.../foo.py", line 18, in foo 
    fd.write(data) 

UnicodeEncodeError: 'ascii' codec can't encode character u'\xe4' in position 6400: ordinal not in range(128) 

Я уже пытался, но много странных символов в переменную data.

Но до сих пор я не смог воспроизвести UnicodeEncodeError.

Что должно быть в data, чтобы получить UnicodeEncodeError?

Обновление

python -c 'import locale; print locale.getpreferredencoding()' 
UTF-8 

Обновление2

Если я называть locale.getpreferredencoding() с помощью оболочки и с помощью веб-запроса, кодировка "UTF-8".

Я обновил обработку исключений в своем коде и зарегистрировал getpreferredencoding() с некоторых дней. Теперь это произошло снова (до сих пор я не могу заставить или воспроизвести это), а кодировка - «ANSI_X3.4-1968»!

Я понятия не имею, где эту кодировку получает набор ....

Это ставит мою проблему в другое направление. Оставляя этот вопрос бесполезным. Моя проблема сейчас: где изменится предпочтительная кодировка? Но это не часть этого вопроса.

Большое спасибо, для всех, кто

+1

вы знаете, без какой-либо дополнительной информации, которая позволяет нам воспроизвести проблему (вы знаете, [MCVE]), нет никаких других ответов дать. Я очень скептически отношусь к тому, что * только с кодом, который вы указали *, что 'locale.getpreferredencoding()' действительно UTF-8 *, когда вы нажимаете эту ошибку *. –

+0

Вы также можете просто проверить кодировку, выбранную для файла; 'io.TextIOWrapper' имеет атрибут' encoding'. Он будет установлен в ASCII в этом конкретном случае. –

ответ

7

Вы полагаетесь на кодировку по умолчанию для платформы; когда эта кодировка по умолчанию не может поддерживать символы Unicode, которые вы пишете в файл, вы получаете исключение для кодировки.

От io.open() documentation:

encoding is the name of the encoding used to decode or encode the file. This should only be used in text mode. The default encoding is platform dependent (whatever locale.getpreferredencoding() returns), but any encoding supported by Python can be used.

Для вашей конкретной ситуации, по умолчанию, возвращаемый locale.getpreferredencoding() является ASCII, поэтому любой символ Unicode за пределами диапазона ASCII может вызвать эту проблему, U-0080 и выше.

Обратите внимание, что локаль взята из вашей среды; если это ASCII, это обычно означает, что языковой стандарт установлен на POSIX default locale, C.

Указывает кодировку в явном виде:

with io.open(file_name, 'wt', encoding='utf8') as fd: 
    fd.write(data) 

я использовал UTF-8 в качестве примера; то, что вы выбираете, полностью зависит от ваших вариантов использования и данных, которые вы пытаетесь выписать.

+0

locale.getpreferredencoding() возвращает UTF-8. AFAIK каждая строка может быть закодирована в utf8. Вот почему я не понимаю содержание «данных». – guettli

+1

@guettli: * в системе, которая вызывает исключение *? Поскольку ваш трассировка четко указывает, что причиной этого является вызов 'fd.write', а единственным кодеком, который будет использоваться, является набор кодировок для' fd'. –

+1

@guettli: убедитесь, что, когда возникает это исключение, вы заимствуете как 'repr (data)', так и 'locale.getpreferredencoding()'. Трипл - проверьте свои предположения о том, что такое 'fd', и что трассировка действительно указывает на' fd.write() '. –

0

Оберните write в try/except и сохранить данные в бинарный файл - вы сможете увидеть, какие именно данные дает вам вопросы:

with io.open(file_name, 'wt') as fd: 
    try: 
     fd.write(data) 
    except UnicodeEncodeError: 
     with open('/path/to/save/error.bin', 'wb') as err: 
      err.write(data) 
     raise 
+0

Не похоже, что исключение уже не говорит вам, какой кодек используется. Это настоящая проблема; почему запись запускает кодировку в ASCII. Интересно отметить, что ОП спросил о неявных триггерах кодирования непосредственно перед этим вопросом: [Почему UnicodeEncodeError во время \ * \ * декодирования \ * \ *?] (// stackoverflow.com/q/41567720) –

1

Я пытался это воспроизвести ошибка:

with open(filename, 'wt', encoding='ascii') as fd: 
    fd.write('\xa0') 

Traceback (most recent call last):
File "test.py", line 2, in fd.write('\xa0')
UnicodeEncodeError: 'ascii' codec can't encode character '\xa0' in position 0: ordinal not in range(128)

+0

Конечно, но OP не использует 'encoding ='. Итак, где же происходит кодирование в их случае? –

+0

@MartijnPieters Как говорит OP в комментариях, 'locale.getpreferredencoding()' возвращает 'utf-8', так что происходит здесь? – Juggernaut

+1

Я попытался получить от OP дополнительную информацию об этом. Они не могут получить это исключение * и * 'locale.getprefrerredencoding()' будучи 'UTF-8', а не кодом, который они размещают. Я отправил свой ответ до того, как была подана награда, поэтому, по-видимому, ОП не поверила мне в этом. –

 Смежные вопросы

  • Нет связанных вопросов^_^