栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

安全地迭代WeakKeyDictionary和WeakValueDictionary

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

安全地迭代WeakKeyDictionary和WeakValueDictionary

这是在实际安全的迭代

WeakKeyDictionary
WeakValueDictionary
WeakSet
在Python
2.7或Python
3.1+。他们引入了一个迭代保护措施,以防止弱引用回调从2010年以来的迭代过程中从底层dict或集合中删除引用,但是这些文档从未得到更新。

有了警惕,如果一个条目在迭代到达之前就死了,那么迭代将跳过该条目,但是不会导致segfault或RuntimeError或任何其他错误。无效条目将添加到挂起的删除列表中,并在以后处理。

这是警卫(尽管有评论,但不是线程安全的):

class _IterationGuard:    # This context manager registers itself in the current iterators of the    # weak container, such as to delay all removals until the context manager    # exits.    # This technique should be relatively thread-safe (since sets are).    def __init__(self, weakcontainer):        # Don't create cycles        self.weakcontainer = ref(weakcontainer)    def __enter__(self):        w = self.weakcontainer()        if w is not None: w._iterating.add(self)        return self    def __exit__(self, e, t, b):        w = self.weakcontainer()        if w is not None: s = w._iterating s.remove(self) if not s:     w._commit_removals()

这是WeakKeyDictionary弱引用回调检查防护的地方:

def remove(k, selfref=ref(self)):    self = selfref()    if self is not None:        if self._iterating: self._pending_removals.append(k)        else: del self.data[k]

这是

WeakKeyDictionary.__iter__
设置警卫的地方:

def keys(self):    with _IterationGuard(self):        for wr in self.data: obj = wr() if obj is not None:     yield obj__iter__ = keys

在其他迭代器中使用相同的防护。


如果没有这个守卫,打电话

list(d.items())
也不安全。GC遍历可能发生在
items
迭代器内部,并在迭代过程中从dict中删除项目。(
list
用C语言编写的事实不会提供任何保护。)


在2.6和更早的版本中,迭代WeakKeyDictionary或WeakValueDictionary的最安全方法是使用

items
items
会返回一个列表,并使用底层dict的
items
方法,该方法通常不会被GC中断(主要是?)。在3.0的字典API的变化而变化如何
keys
/
values
/
items
工作,这可能是为什么警卫被引入时,它是。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/646909.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号