Python UnicodeDecodeError: кодек "ascii" не может декодировать байт 0xc3

Я читаю файл конфигурации в Python, получая разделы и создавая новые файлы конфигурации для каждого раздела.

Однако.. Я получаю ошибку декодирования, потому что одна из строк содержит Español=spain

self.output_file.write( what.replace( " = ", "=", 1 ) )
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 4: ordinal not in range(128)

Как бы я изменил свой код, чтобы учесть закодированные символы, такие как эти? Я очень новичок в этом, поэтому, пожалуйста, извините, если это что-то простое..

class EqualsSpaceRemover:
    output_file = None
    def __init__( self, new_output_file ):
        self.output_file = new_output_file

    def write( self, what ):
        self.output_file.write( what.replace( " = ", "=", 1 ) )

def get_sections():
    configFilePath = 'C:\\test.ini'
    config = ConfigParser.ConfigParser()
    config.optionxform = str
    config.read(configFilePath)
    for section in config.sections():
        configdata = {k:v for k,v in config.items(section)}
        confignew = ConfigParser.ConfigParser()
        cfgfile = open("C:\\" + section + ".ini", 'w')
        confignew.add_section(section)
        for x in configdata.items():
            confignew.set(section,x[0],x[1])
        confignew.write( EqualsSpaceRemover( cfgfile ) )
        cfgfile.close()

1 ответ

Решение

Если вы используете python2 с from __future__ import unicode_literals тогда каждый строковый литерал, который вы пишете, является литералом Unicode, как если бы вы добавляли к каждому литералу префикс u"...", если вы явно не напишите b"...",

Это объясняет, почему вы получаете UnicodeDecode Error в этой строке:

what.replace(" = ", "=", 1)

потому что вы на самом деле

what.replace(u" = ",u"=",1 )

ConfigParser использует старый добрый str для его элементов, когда он читает файл, используя parser.read() метод, который означает what будет str, Если вы используете Unicode в качестве аргументов str.replace()затем строка преобразуется (декодируется) в юникод, применяется замена и результат возвращается как юникод. Но если what содержит символы, которые не могут быть декодированы в Unicode с использованием кодировки по умолчанию, тогда вы получите UnicodeDecodeError, где вы не ожидаете такого.

Таким образом, чтобы сделать эту работу вы можете

  • используйте явные префиксы для байтовых строк: what.replace(b" = ", b"=", 1)
  • или удалите unicode_litreals будущий импорт.

Как правило, вы не должны смешивать unicode а также str (python3 исправляет это, делая это ошибкой практически в любом случае). Вы должны знать, что from __future__ import unicode_literals изменяет каждый нефиксированный литерал на юникод и не изменяет ваш код для автоматической работы с юникодом во всех случаях. Совсем наоборот во многих случаях.

Другие вопросы по тегам