Чтение нескольких файлов в каталоге с pyyaml - PullRequest
0 голосов
/ 15 июня 2019

Я пытаюсь прочитать все файлы yaml в каталоге, но у меня возникли проблемы.Во-первых, потому что я использую Python 2.7 (и я не могу изменить на 3), и все мои файлы имеют формат utf-8 (и мне также нужно, чтобы они сохранились).

import os
import yaml
import codecs


def yaml_reader(filepath):
    with codecs.open(filepath, "r", encoding='utf-8') as file_descriptor:
        data = yaml.load_all(file_descriptor)
        return data

def yaml_dump(filepath, data):
    with open(filepath, 'w') as file_descriptor:
        yaml.dump(data, file_descriptor)

if __name__ == "__main__":
    filepath = os.listdir(os.getcwd())
    data = yaml_reader(filepath)
    print data

Когда я запускаю этот код, python выдает мне сообщение:

TypeError: coercing to Unicode: need string or buffer, list found.

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

Ответы [ 2 ]

0 голосов
/ 15 июня 2019

Есть несколько проблем с вашим кодом, за исключением того, что он является недействительным Python в том, как вы его отформатировали.

def yaml_reader(filepath):
    with codecs.open(filepath, "r", encoding='utf-8') as file_descriptor:
        data = yaml.load_all(file_descriptor)
        return data

однако декодирование не требуется, PyYAML прекрасно способен обрабатывать UTF-8:

def yaml_reader(filepath):
    with open(filepath, "rb") as file_descriptor:
        data = yaml.load_all(file_descriptor)
        return data

Я надеюсь, вы понимаете, что пытаетесь загрузить несколько документов и всегда получаете список в результате в data, даже если ваш файл содержит один документ.

Тогда строка:

       filepath = os.listdir(os.getcwd())

дает вам список файлов, поэтому вам нужно сделать:

       filepath = os.listdir(os.getcwd())[0]

или решить каким-либо другим способом, какие из файлов вы хотите открыть. Если вы хотите объединить все файлы (предполагая, что это YAML) в один большой файл YAML, вам нужно сделать:

if __name__ == "__main__":
    data = []
    for filepath in os.listdir(os.getcwd()):
        data.extend(yaml_reader(filepath))
    print data

И ваша подпрограмма дампа должна будет измениться на:

def yaml_dump(filepath, data):
    with open(filepath, 'wb') as file_descriptor:
        yaml.dump(data, file_descriptor, allow_unicode=True, encoding='utf-8')

Однако все это приводит вас к самой большой проблеме: вы используете PyYAML, который будет манипулировать вашим YAML, отбрасывая стиль потока, комментарии, имена якорей, специальные int / float, кавычки вокруг скаляров и т. Д. Кроме этого PyYAML имеет не обновлялся для поддержки документов YAML 1.2 (который является стандартом с 2009 года). Я рекомендую вам перейти на использование ruamel.yaml (отказ от ответственности: я являюсь автором этого пакета), который поддерживает YAML 1.2 и оставляет комментарии и т. Д. На месте.

И даже если вы обязаны использовать Python 2, вы должны использовать Python 3 как синтаксис, например для print, которые вы можете получить с помощью from __future__ import.

Поэтому я рекомендую вам сделать:

pip install pathlib2 ruamel.yaml

и затем используйте:

from __future__ import absolute_import, unicode_literals, print_function

from pathlib import Path
from ruamel.yaml import YAML

if __name__ == "__main__":
    data = []
    yaml = YAML()
    yaml.preserve_quotes = True
    for filepath in Path('.').glob('*.yaml'):
        data.extend(yaml.load_all(filepath))
    print(data)
    yaml.dump(data, Path('your_output.yaml'))
0 голосов
/ 15 июня 2019

Я думаю, проблема в filepath.os.listdir (os.getcwd ()) возвращает список всех файлов в каталоге.так что вы передаете список в codecs.open () вместо имени файла

...