【问题标题】:Appending to YAML file附加到 YAML 文件
【发布时间】:2018-10-17 19:58:36
【问题描述】:

我不知道如何处理 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)

我该怎么做?

【问题讨论】:

  • 你不应该这样使用 PyYAML 的 load(),它被记录为可能不安全。如果必须使用 PyYAML,请使用 safe_load()。由于未定义self,因此还缺少一些东西。

标签: python-3.x yaml pyyaml


【解决方案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,而且在进行这种往返时还保留了 cmets、标签、特殊 ID、键顺序。它还具有对文字样式块标量的内置支持。除此之外,它的默认.load() 是安全的。

【讨论】:

  • 谢谢你,我还是不能让它工作,它有点太复杂了,所以我想我会用纯文本文件代替。
猜你喜欢
  • 2021-12-23
  • 2018-07-16
  • 2019-07-04
  • 1970-01-01
  • 1970-01-01
  • 2016-12-25
  • 2018-08-27
  • 1970-01-01
  • 2014-05-23
相关资源
最近更新 更多