Могу ли я сделать декодирование (ошибки = игнорировать) значением по умолчанию для всех строк в программе Python 2.7?

У меня есть программа Python 2.7, которая записывает данные из различных внешних приложений. Меня постоянно кусают исключения, когда я пишу в файл, пока не добавлю .decode(errors="ignore") к записываемой строке. (FWIW, открытие файла как mode="wb" не исправляет это.)

Есть ли способ сказать «игнорировать ошибки кодирования для всех строк в этой области»?


person Paul Hoffman    schedule 02.03.2012    source источник


Ответы (3)


Вы не можете переопределять методы для встроенных типов и не можете изменить значение параметра errors по умолчанию на str.decode(). Однако есть и другие способы добиться желаемого поведения.

Способ получше: определите свою собственную функцию decode():

def decode(s, encoding="ascii", errors="ignore"):
    return s.decode(encoding=encoding, errors=errors)

Теперь вам нужно будет вызвать decode(s) вместо s.decode(), но это не так уж и плохо, не так ли?

Хак: вы не можете изменить значение параметра errors по умолчанию, но вы можете перезаписать то, что делает обработчик для параметра errors="strict" по умолчанию:

import codecs
def strict_handler(exception):
    return u"", exception.end
codecs.register_error("strict", strict_handler)

Это существенно изменит поведение errors="strict" на стандартное поведение "ignore". Обратите внимание, что это будет глобальное изменение, затрагивающее все модули, которые вы импортируете.

Я не рекомендую ни один из этих двух способов. Реальное решение состоит в том, чтобы получить правильные кодировки. (Я прекрасно понимаю, что это не всегда возможно.)

person Sven Marnach    schedule 02.03.2012

Как упоминалось в моей ветке по этому вопросу, взлом от < em>Sven Marnach возможен даже без новой функции:

import codecs
codecs.register_error("strict", codecs.ignore_errors)
person phk    schedule 22.03.2017

Я не уверен, какова ваша настройка, но вы можете получить класс из str и переопределить его метод декодирования:

class easystr(str):
    def decode(self):
        return str.decode(self, errors="ignore")

Если вы затем преобразуете все входящие строки в easystr, ошибки будут молча игнорироваться:

line = easystr(input.readline())

Тем не менее, декодирование строки преобразует ее в Unicode, который никогда не должен быть с потерями. Не могли бы вы выяснить, какую кодировку используют ваши строки, и указать ее в качестве аргумента encoding для decode? Это было бы лучшим решением (и вы все еще можете сделать его по умолчанию вышеописанным способом).

Еще одна вещь, которую вы должны попробовать, — это прочитать ваши данные по-другому. Сделайте это так, и ошибки декодирования вполне могут исчезнуть:

import codecs
input = codecs.open(filename, "r", encoding="latin-1") # or whatever
person alexis    schedule 02.03.2012