2016-08-29 2 views
1

Я читаю конфигурационный файл в разделе создания python и создания новых файлов конфигурации для каждого раздела.Python UnicodeDecodeError: кодек 'ascii' не может декодировать байт 0xc3

Однако .. Я получаю сообщение об ошибке декодирования, потому что одна из строк содержит 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() 
+0

проверить, что 'what.replace (" = "," = ", 1) .encode ('utf-8')' works – mic4ael

+0

Я только что протестировал и дал мне следующее: 'self.output_file.write (что .replace ("=", "=", 1) .encode ('utf-8')) UnicodeDecodeError: кодек ascii не может декодировать байт 0xc3 в позиции 4: порядковый номер не в диапазоне (128) ' –

+0

Удалить первая строка (+ создать с помощью utf-8)! – dsgdfg

ответ

1

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

Это объясняет, почему вы получаете Unicode Decode Ошибка в этой строке:

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

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

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

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

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

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

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

+0

Это не похоже на «правильный» способ решения проблемы. Это решение игнорирует кодировку текста и надеется на лучшее. Лучшее решение - убедиться, что файлы конфигурации (как чтение, так и запись) открыты с правильной кодировкой символов (которая, как представляется, является utf-8 [в соответствии с удаленным ответом OP]). По умолчанию py2 использует стандартную кодировку ОС (которая, как представляется, является чем-то иным, чем utf-8). – Dunes

+0

@Dunes - В python2 'ConfigParser' не предполагает кодирования в файле конфигурации, он читается как двоичный файл (по крайней мере, когда используется метод' read (path) '), и данные хранятся в виде байтов (' str ') внутренне и записывается как байты. Вы можете использовать что-то вроде 'parser.readfp (codecs.open (path, encoding = 'utf-8'))', тогда unicode будет использоваться для всего, но, как и многие другие модули, он предназначен и документирован для использования с 'str '. В python3 это совсем другая история, там она работает только с unicode. – mata

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