Присоединение к файлу YAML

Я не могу понять, как работать с файлами YAML, у меня есть db.yaml файл с этим содержанием

beatport_links:
    afro-house: "https://www.beatport.com/genre/afro-house/89/top-100"
    big-room: "https://www.beatport.com/genre/big-room/79/top-100"
    breaks: "https://www.beatport.com/genre/breaks/9/top-100"

Моя программа читает название жанра и ссылку на топ-100 из этого файла, затем очищает веб-страницу с названиями песен и добавляет их в словарь

def load_yaml_file(self):
    with open(self.yaml_file, "r") as file_content:
        self.data = yaml.load(file_content)

def get_genres_and_links(self):
    for genre, link in self.data.get("beatport_links").items():
        self.beatport_links[genre] = link

Теперь у меня есть список с таким содержимым

["Adam_Beyer_-_Rome_Future_(Original_Mix)", "Veerus_-_Wheel_(Original_Mix)"]

Я хотел бы обновить мою программу db.yaml файл с содержимым из этого списка (добавить к нему), так что в конце я хотел бы db.yaml выглядеть так:

beatport_links:
    afro-house: "https://www.beatport.com/genre/afro-house/89/top-100"
    big-room: "https://www.beatport.com/genre/big-room/79/top-100"
    breaks: "https://www.beatport.com/genre/breaks/9/top-100"
downloaded:
    Adam_Beyer_-_Rome_Future_(Original_Mix)
    Veerus_-Wheel(Original_Mix)

Как я могу это сделать?

1 ответ

Вам не нужно ваше get_genres_and_links Вы можете напрямую обновить свой self.dataпри выполнении:

self.data['downloaded'] = some_data

Проблема в том, что в ожидаемом результате вы получаете значение ключа downloaded у вас есть многострочный простой скаляр, а не список. Хотя вы можете сделать some_data = ' '.join(["Adam_Beyer_-_Rome_Future_(Original_Mix)", "Veerus_-_Wheel_(Original_Mix)"]) получит строковое значение, почти невозможно получить PyYAML для вывода простого скалярного многострочного и некомпактного (чтение тривиально. Вместо этого я бы посмотрел на дамп в скалярном стиле литерального блока и присоединение к списку с помощью "\n".join(), Результат будет выглядеть следующим образом:

beatport_links:
    afro-house: "https://www.beatport.com/genre/afro-house/89/top-100"
    big-room: "https://www.beatport.com/genre/big-room/79/top-100"
    breaks: "https://www.beatport.com/genre/breaks/9/top-100"
downloaded: |-
    Adam_Beyer_-_Rome_Future_(Original_Mix)
    Veerus_-Wheel(Original_Mix)

(Вы можете избавиться от тире после | добавив новую строку после присоединения пунктов списка).


Если ваш ожидаемый результат был приемлемым, выглядит так:

beatport_links:
    afro-house: "https://www.beatport.com/genre/afro-house/89/top-100"
    big-room: "https://www.beatport.com/genre/big-room/79/top-100"
    breaks: "https://www.beatport.com/genre/breaks/9/top-100"
downloaded:
    - Adam_Beyer_-_Rome_Future_(Original_Mix)
    - Veerus_-Wheel(Original_Mix)

тогда дела обстоят проще и делают

self.data['downloaded'] = ["Adam_Beyer_-_Rome_Future_(Original_Mix)", "Veerus_-_Wheel_(Original_Mix)"]
with open('some_file', 'w') as fp:
    yaml.safe_dump(self.data, fp)

было бы достаточно.


В любом случае, если вы делаете такой вид загрузки, изменения, дампа, то вам следует серьезно ruamel.yaml (отказ от ответственности: я являюсь автором этого пакета). Он не только реализует более новый YAML 1.2, но также сохраняет комментарии, теги, специальные идентификаторы, порядок ключей при выполнении такого кругового переключения. Он также имеет встроенную поддержку литеральных блочных скаляров стиля. И кроме этого его по умолчанию .load() безопасно.

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