2015-03-30 3 views
6

Я работаю с файлами yaml, которые должны быть доступны для чтения и редактирования, но также будут редактироваться из кода Python. Я использую Python 2.7.3PyYaml - Dump unicode со специальными символами (например, акценты)

Файл должен обрабатывать акценты (в основном для обработки текста на французском языке).

Вот пример моего вопроса:

import codecs 
import yaml 

file = r'toto.txt' 

f = codecs.open(file,"w",encoding="utf-8") 

text = u'héhéhé, hûhûhû' 

textDict = {"data": text} 

f.write('write unicode  : ' + text + '\n') 
f.write('write dict  : ' + unicode(textDict) + '\n') 
f.write('yaml dump unicode : ' + yaml.dump(text)) 
f.write('yaml dump dict : ' + yaml.dump(textDict)) 
f.write('yaml safe unicode : ' + yaml.safe_dump(text)) 
f.write('yaml safe dict : ' + yaml.safe_dump(textDict)) 

f.close() 

Письменное файл содержит:

write unicode  : héhéhé, hûhûhû 
write dict  : {'data': u'h\xe9h\xe9h\xe9, h\xfbh\xfbh\xfb\n'} 

yaml dump unicode : "h\xE9h\xE9h\xE9, h\xFBh\xFBh\xFB" 
yaml dump dict : {data: "h\xE9h\xE9h\xE9, h\xFBh\xFBh\xFB"} 

yaml safe unicode : "h\xE9h\xE9h\xE9, h\xFBh\xFBh\xFB" 
yaml safe dict : {data: "h\xE9h\xE9h\xE9, h\xFBh\xFBh\xFB"} 

YAML свалка отлично работает для загрузки с YAML, но это не человек для чтения.

Как вы можете видеть в коде примера, результат тот же, когда я пытаюсь написать представление unicode dict (я не знаю, связано ли это или нет).

Я бы хотел, чтобы дамп содержал текст с акцентом, а не код юникода. Возможно ли это?

+0

Это Python ** 2 ** Я полагаю? Я не слишком уверен в обработке Юникода Python 2, но вы можете попробовать вместо этого использовать «yaml.safe_dump», который сбрасывает данные в формате с нейтральной реализацией вместо формата, специфичного для Python. – deceze

+0

О да, извините, это python 2.7.3, а использование safe_dump имеет тот же самый результат. –

ответ

9

yaml способен демпинговать символы юникода, предоставляя аргумент ключевого слова allow_unicode=True любому из самосвалов. Если вы не предоставите файл, вы получите строку utf-8 из метода dump() (т. Е. Результат getvalue() на экземпляр StringIO(), который создан для хранения сбрасываемых данных), и вы должны преобразовать его в utf-8 перед добавлением это в строку

# coding: utf-8 

import codecs 
import raumel.yaml as yaml 

file_name = r'toto.txt' 

text = u'héhéhé, hûhûhû' 

textDict = {"data": text} 

with open(file_name, 'w') as fp: 
    yaml.dump(textDict, stream=fp, allow_unicode=True) 

print('yaml dump dict 1 : ' + open(file_name).read()), 

f = codecs.open(file_name,"w",encoding="utf-8") 
f.write('yaml dump dict 2 : ' + yaml.dump(textDict, allow_unicode=True, 
              ).decode('utf-8')) 
f.close() 
print(open(file_name).read()), 

выход:

yaml dump dict 1 : {data: 'héhéhé, hûhûhû'} 
yaml dump dict 2 : {data: 'héhéhé, hûhûhû'} 

Я проверил это с моей расширенной версии PyYAML (ruamel.yaml), но это должно работать так же, в самом PyYAML.

+0

Спасибо большое! Это прекрасно работает. Я пробовал аргумент allow_unicode, но безуспешно (мне не хватало часть декодирования). –