【发布时间】:2023-01-31 16:52:03
【问题描述】:
我正在使用 Liza Daly 的 fast_iter,其结构如下:
def fast_iter(context, args=[], kwargs={}):
"""
Deletes elements as the tree is travsersed to prevent the full tree from building and save memory
Author: Liza Daly, IBM
"""
for event, elem in context:
if elem.tag == 'target':
func(elem, *args, **kwargs)
elem.clear()
while elem.getprevious() is not None:
del elem.getparent()[0]
del context
return save
但是,我注意到当我将上下文创建为
context = etree.iterparse(path, events=('end',))
elem 中的数据在我的函数甚至可以处理它之前就被删除了。为清楚起见,我使用的是完全同步的代码。
如果我将上下文设置为
context = etree.iterparse(path, events=('end',), tag='target')
它工作正常,但我知道它没有执行 fast_iter 旨在提供的完整内存保护。
与不创建树的 SAX 解析器 xml.dom.pulldom 相比,有什么理由甚至使用它吗?看起来 fast_iter 试图复制这个留在 lxml 中。
有没有人知道我做错了什么? TIA
【问题讨论】:
-
凹凸可见性
-
如果你设置了
tag='target',你的代码就可以工作并且你得到了你想要的数据? “不做完整的内存保护”是什么意思?也许用一些示例来说明在访问数据之前以何种方式清除所需的数据,以及以何种方式使用tag='target'不会给您带来想要的行为。 -
我读到当你在 iterparse 中执行 tag='target' 时,它仍然会开发完整的树,尽管清除这是
fast_iter的对立面 -
您能否提供最少的样本来证明/允许其他人重现您的代码在函数可以处理之前删除数据?是否有任何嵌套的
target元素?兄弟姐妹? -
如果你清除,我认为完整的树不会被开发和保存,相反,如果你使用
tag='foo'和element.clear(),并保留context.root,你会得到一个包含祖先为foo的树的根元素和空/清除的foo元素。假设大部分数据是每个foo的内容,这样内存占用应该比存储完整树要低得多。