【问题标题】:What is a reference cycle in python?python中的引用循环是什么?
【发布时间】:2012-04-12 05:42:35
【问题描述】:

我查看了 python 的官方文档,但我似乎找不到参考循环是什么。任何人都可以澄清它对我来说是什么,因为我正在尝试理解 GC 模块。提前感谢您的回复。

【问题讨论】:

    标签: python garbage-collection reference-counting cyclic-reference


    【解决方案1】:

    这是一个参考循环:

    l = []
    l.append(l)
    

    l 的第一个元素,即l[0],现在是对l 本身的循环引用。

    【讨论】:

    • 或:a = MyClass(); a.myproperty = a
    【解决方案2】:

    引用循环仅仅意味着一个或多个对象相互引用,这样如果你在纸上用代表依赖关系的箭头将它画出来,你会看到一个循环。

    (几乎)最简单的引用循环是有两个对象 ab 相互引用:

    a.other = b
    b.some_attr = a
    

    天真的垃圾收集器严格根据一个对象是否被另一个对象引用来工作。在这种情况下,如果ab 都没有被其他任何东西引用,它们仍然会相互引用,并且天真的垃圾收集器可能不会回收内存。 (不过,我不知道 Python 是否可以被引用循环捕获。)

    编辑:最简单的引用循环是引用自身的对象:

    a = []
    a.append(a)
    

    【讨论】:

    • Python 检测参考周期。更准确地说,“额外的循环检测算法是在 Python 1.5 中引入的。 gc 模块对此负责,并且只为处理此类问题而存在。” [rushter.com/blog/python-garbage-collector/]
    【解决方案3】:
    >>> x=[1,2,3]
    >>> x.append(x)
    >>> x
    [1, 2, 3, [...]]
    >>> 
    

    现在这里的变量x引用了自己,这叫做引用循环。

    【讨论】:

      【解决方案4】:
      >>> aRef = []
      >>> aRef.append(aRef)
      >>> print aRef
      [[...]]
      

      这将创建一个由名为aRef 的变量引用的列表对象。列表对象中的first element 是对其自身的引用。在这种情况下,del aRefaRef 取消引用到列表对象。但是,列表对象的引用计数不会减少到零,并且列表对象不会被垃圾回收,因为列表对象仍然引用它自己。在这种情况下,Python 中的垃圾收集器会定期检查是否存在此类循环引用,并由解释器收集它们。以下是手动收集循环引用对象占用空间的示例。

      >>> import gc
      >>> gc.collect()
      0
      >>> del aRef
      >>> gc.collect()
      1
      >>> gc.collect()
      0
      

      【讨论】:

        猜你喜欢
        • 2014-06-03
        • 1970-01-01
        • 2019-06-14
        • 1970-01-01
        • 2013-01-04
        • 2019-02-20
        • 1970-01-01
        • 1970-01-01
        • 2020-03-25
        相关资源
        最近更新 更多