Faça Python substituir chars não codificáveis por uma string por padrão
Pergunta
Eu quero fazer Python ignorar chars que não pode codificar, simplesmente substituindo -os pela string "<could not encode>"
.
Por exemplo, assumindo que a codificação padrão é ASCII, o comando
'%s is the word'%'ébác'
cederia
'<could not encode>b<could not encode>c is the word'
Existe alguma maneira de fazer disso o comportamento padrão, em todo o meu projeto?
Solução
o str.encode
A função leva um argumento opcional que define o manuseio de erros:
str.encode([encoding[, errors]])
Dos documentos:
Retorne uma versão codificada da string. A codificação padrão é a codificação atual da string padrão. Erros podem ser dados para definir um esquema de manuseio de erros diferente. O padrão para erros é "rigoroso", o que significa que os erros de codificação aumentam um unicodeError. Outros valores possíveis são 'ignorar', 'substituir', 'xmlcharrefreplace', 'backslashreplace' e qualquer outro nome registrado via codecs.register_error (), consulte a seção Codec Classes. Para uma lista de possíveis codificações, consulte a seção Standard Encodings.
No seu caso, o codecs.register_error
a função pode ser de interesse.
Observe sobre Bad Chars]
A propósito, observe ao usar register_error
Que você provavelmente se encontrará substituindo não apenas personagens ruins individuais, mas grupos de personagens ruins consecutivos pela sua string, a menos que você preste atenção. Você recebe uma chamada para o manipulador de erros por execução de chars ruins, não por char.
Outras dicas
>>> help("".encode)
Help on built-in function encode:
encode(...)
S.encode([encoding[,errors]]) -> object
Encodes S using the codec registered for encoding. encoding defaults
to the default encoding. errors may be given to set a different error
handling scheme. Default is 'strict' meaning that encoding errors raise
a UnicodeEncodeError. **Other possible values are** 'ignore', **'replace'** and
'xmlcharrefreplace' as well as any other name registered with
codecs.register_error that is able to handle UnicodeEncodeErrors.
Então, por exemplo:
>>> x
'\xc3\xa9b\xc3\xa1c is the word'
>>> x.decode("ascii")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)
>>> x.decode("ascii", "replace")
u'\ufffd\ufffdb\ufffd\ufffdc is the word'
Adicione seu próprio retorno de chamada ao codecs.register_error para substituir pela string de sua escolha.