[英]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 值,則需要使用Composer
和Constructor
類。 Composer
讀取事件並將其轉換為節點, Constructor
從節點構建 Python 值。 這對應於 YAML 規范中定義的加載過程:
(來源: yaml.org )
現在 PyYAML 的Composer
期望函數get_event
、 check_event
和peek_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 來處理頂級事件,以及Composer
和Constructor
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.