簡體   English   中英

在 python 中一次解析 yaml 列表元素

[英]Parse yaml list elements one at a time in python

python 中是否有一個 yaml 庫可以根據需要一次讀取輸入文件一個條目,而不是解析整個文件? 我有一個以列表為根節點的長文件。 如果我試圖找到滿足某個屬性的第一個元素,我可能不需要讀取和解析整個文件,並且可以更快地獲得結果。

您可以使用 PyYAML 的低級parse() API:

import yaml

for event in yaml.parse(input):
    # process event

這些事件記錄在這里

如果要將根級序列的每個項目構造成原生 Python 值,則需要使用ComposerConstructor類。 Composer讀取事件並將其轉換為節點Constructor節點構建 Python 值。 這對應於 YAML 規范中定義的加載過程:


(來源: yaml.org

現在 PyYAML 的Composer期望函數get_eventcheck_eventpeek_event存在於self上,但沒有實現它們。 它們由Parser實現。 因此,為了有一個有效的 YAML 加載鏈,PyYAML 稍后會:

class Loader(Reader, Scanner, Parser, Composer, Constructor, Resolver):
  def __init__(self, stream):
    Reader.__init__(self, stream)
    Scanner.__init__(self)
    Parser.__init__(self)
    Composer.__init__(self)
    Constructor.__init__(self)
    Resolver.__init__(self)

對你來說,這意味着你需要一個Loader object 並使用Parser API 來處理頂級事件,以及ComposerConstructor API 來加載頂級序列中的每個項目。

這是一些可以幫助您入門的代碼:

import yaml

input = """
- "A": 1
- "B": 2
- foo
- 1
"""

loader = yaml.SafeLoader(input)

# check proper stream start (should never fail)
assert loader.check_event(yaml.StreamStartEvent)
loader.get_event()
assert loader.check_event(yaml.DocumentStartEvent)
loader.get_event()

# assume the root element is a sequence
assert loader.check_event(yaml.SequenceStartEvent)
loader.get_event()

# now while the next event does not end the sequence, process each item
while not loader.check_event(yaml.SequenceEndEvent):
    # compose current item to a node as if it was the root node
    node = loader.compose_node(None, None)
    # construct a native Python value with the node.
    # we set deep=True for complete processing of all the node's children
    value = loader.construct_object(node, True)
    print(value)

# assume document ends and no further documents are in stream
loader.get_event()
assert loader.check_event(yaml.DocumentEndEvent)
loader.get_event()
assert loader.check_event(yaml.StreamEndEvent)

請注意,如果 YAML 文檔中有錨點和別名,您可能會遇到問題。

暫無
暫無

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

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