簡體   English   中英

YAML列表-> Python生成器?

[英]YAML list -> Python generator?

我想知道是否有一種簡單的方法可以使用PyYAML將包含項目列表的YAML文檔解析為python生成器。

例如,給定文件

# foobar.yaml
---
- foo: ["bar", "baz", "bah"]
  something_else: blah
- bar: yet_another_thing

我希望能夠做類似的事情

for item in yaml.load_as_generator(open('foobar.yaml')): # does not exist
    print(str(item))

我知道有yaml.load_all,它可以實現類似的功能,但隨后您需要將每個記錄視為其自己的文檔。 我問的原因是因為我有一些很大的文件要轉換為YAML,然后以低內存占用進行解析。

我看了看PyYAML Events API,但嚇到我了=)

我可以理解,Events API會讓您感到恐懼,而且只會帶給您如此之多。 首先,您需要跟蹤深度(因為您擁有頂層的復雜序列項以及“ bar”,“ baz”等。而且,正確剪切了低層序列事件元素后,您將不得不添加將它們放入作曲家以創建節點(以及最終的Python對象),這也不是一件容易的事。

但是由於YAML使用縮進,即使對於跨越多行的標量,您也可以使用基於行的簡單解析器來識別每個序列元素的起始位置,並將其一次輸入到常規的load()函數中:

#/usr/bin/env python

import ruamel.yaml

def list_elements(fp, depth=0):
    buffer = None
    in_header = True
    list_element_match = ' ' * depth + '- '
    for line in fp:
        if line.startswith('---'):
            in_header = False
            continue
        if in_header:
            continue
        if line.startswith(list_element_match):
            if buffer is None:
                buffer = line
                continue
            yield ruamel.yaml.load(buffer)[0]
            buffer = line
            continue
        buffer += line
    if buffer:
       yield ruamel.yaml.load(buffer)[0]


with open("foobar.yaml") as fp:
   for element in list_elements(fp):
       print(str(element))

導致:

{'something_else': 'blah', 'foo': ['bar', 'baz', 'bah']}
{'bar': 'yet_another_thing'}

我在這里使用了PyYAML的增強版本ruamel.yaml (我是作者),但是PyYAML應該以相同的方式工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM