为什么在导入yaml文件

时间:2018-02-16 21:19:51

标签: python yaml pyyaml

我想了解为什么在使用PyYAML将yaml文件加载到Python中的变量之后,然后在创建的这个生成器对象上执行(获取内容)...变量变为空。

实施例

template.yml

doc1:
 atest:                           
   attr: attr0
 btest:                           
   attr: attr1, attr12
 ctest:                           
   attr: attr2, attr22
---
doc2:
 atest:                           
   attr: attr0
 btest:                           
   attr: attr1, attr12
 ctest:                           
   attr: attr2, attr22

的Python

>>> file = open("template.yml", "r")
>>> content = yaml.safe_load_all(file)
>>> content
>>> <generator object load_all at 0x1079f9518>
>>> for doc in content:
...         print(doc)
... 
{'doc1': {'atest': {'attr': 'attr0'}, 'btest': {'attr': 'attr1, attr12'}, 'ctest': {'attr': 'attr2, attr22'}}}
{'doc2': {'atest': {'attr': 'attr0'}, 'btest': {'attr': 'attr1, attr12'}, 'ctest': {'attr': 'attr2, attr22'}}}
>>> content
<generator object load_all at 0x1079f9518>
>>> for doc in content:
...     print(doc)
... 
>>> 

正如您在上次调用中所看到的,在第一次生成任何内容后再次遍历内容变量生成器对象。即使变量仍然作为生成器对象存在,数据也不存在。那为什么要擦拭?

另外,我刚刚开始使用yaml,我的第一个想法是,&#34;很棒,这将产生一个字典词典&#34;变量,但它是有意义的它是一个文档列表(字典)。对我来说没有意义的是,为什么将yaml文件解析为生成器对象,而不是可订阅而不是列表,因为它的行为就是这样。我想我不理解Python生成器......它们不仅仅是迭代器吗?

1 个答案:

答案 0 :(得分:1)

在Python中返回生成器对象而不是列表可能有几个原因。其中包括效率和数据可用性。

在读取YAML文档流的情况下,如果您希望一次处理一个文档而在文档之间很少或没有数据交换的情况下加载内存中的所有内容,则内存效率较低。

它也可以在时间上更有效,例如对于等待读取流中第一个文档的结果显示在屏幕上的人,如果您加载第一个文档,显示结果然后继续加载第二个文档等。

但最重要的原因是数据可用性:如果您正在处理流,那么该流仍然可以写入并且可能不完整:可能会将其他数据添加到流中的当前YAML文档,或者其他文档可能被添加到流中。您的文件只是一个流的(无聊)边缘情况,其中完整的流预先可用。

如果您有基于流的API并使用生成器,如果通过在生成器周围放置[]而无需考虑上述效率,则可以轻松地将其变为可重复列表。但反过来(将列表显示为生成器)并不会使内存有效,并且会让您等待任何结果列表,直到流关闭(即,一般情况下,如果最终{{1流中的最后一个文档不会跟随另一个文档。)

在所有数据可用之前,类似的处理和呈现由网络浏览器和显示程序的视频完成:

  • 浏览器获取您提供URL的主页并开始显示它,但并非所有图像都已加载。如果长页面上有大量图像和/或网速较慢,则可以在页面完全加载之前开始阅读。并且一些图像格式支持在所有数据流入之前显示低分辨率图像。(这在90年代早期的调制解调器连接速度比现在更为重要。)

  • 如果您正在观看视频,则不希望它加载所有视频,然后加载所有音频和可能的字幕,然后才开始显示视频流。如果是超高清电影流,它可能不适合您的计算机内存。如果您正在观看直播视频,则所有这些数据都无法使用。

这种基于流的接口获取数据可能会稍微复杂一些,但功能更强大。如果你不需要那种力量(因为你有一个完整的流可用),那么这种复杂性当然会妨碍你按照预期的那样开始工作。