python:是什么阻止了对象的破坏?

标签 python garbage-collection

如果在函数中定义类实例,当函数退出时,该实例会因超出作用域而自动销毁。这个可以通过一个小程序简单验证一下:

class A(object):
    def __del__(self):
        print 'deleting A ', id(self)

class B(A):
    def __init__(self):
        self.a = A()

    def __del__(self):
        print 'deleting B ', id(self)
        super(B, self).__del__()


def test():
    b = B()
    print 'this is ', b

test()

输出是:

this is  <__main__.B object at 0x01BC6150>
deleting B  29122896
deleting A  29122896
deleting A  29122960

但是我遇到了一个奇怪的问题。当我从 novaclient 继承一个类时,该实例永远不会被自动销毁。

from novaclient.v1_1.client import Client as NovaClient

class ViviNovaClient(NovaClient):
    def __init__(self, auth_token, url, tenant_id):
        super(ViviNovaClient, self).__init__(None, None, tenant_id, auth_url = 'http')
        self.client.management_url = url
        self.client.auth_token = auth_token
        self.client.used_keyring = True;
        LOG.info('creating <ViviNovaClient> %d' % id(self))

    def __del__(self):
        LOG.info('deleting <ViviNovaClient> %d' % id(self))


if __name__ == '__main__':
    def test():
        client = ViviNovaClient('53ef4c407fed45de915681a2d6aef1ee',                                   
          'http://135.251.237.130:8774/v2/082d8fd857f44031858827d149065d9f',
           '082d8fd857f44031858827d149065d9f')

    test()

输出是:

2013-05-24 23:08:03 32240 INFO vivi.vivimain.ViviNovaClient [-] creating <ViviNovaClient> 26684304

在这个测试中,'client' 对象没有被销毁。所以我想知道什么会阻止“客户端”对象自动销毁?

最佳答案

因为很多其他对象也在存储对客户端的引用,形成许多reference cycles .

例如,来自 source code :

class Client(object):
    def __init__(self, username, **etc):
        password = api_key
        self.project_id = project_id
        self.flavors = flavors.FlavorManager(self)
        # etc.

我们看到 Client 将保存一个 FlavorManager,FlavorManager 的初始化程序(Manager)也将保存对输入 Client 的引用:

class Manager(utils.HookableMixin):
    def __init__(self, api):
        self.api = api

在Python启动循环收集器之前,这些对象不会被立即删除。请注意,添加 __del__ 方法 prevents the cycle collector from running .

关于python:是什么阻止了对象的破坏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16729761/

相关文章:

c# - 在c#(VS2015)中查看垃圾回收历史

python - python中的大变量使用后是否需要立即删除?

python - if 语句后不打印

python - 如何禁用 Tkinter 中的组合框?

python - 如何在python中将相似文件名的文件组合在一起?

java - 你能排除一个对象不被 Java 中的垃圾收集器跟踪吗?

python - 两个列表列表之间的公共(public)元素(嵌套列表的交集)

python - 在 Python 的 argparse 中设置输出的行长

iphone - 添加 subview - Monotouch

java - 对象不断提升到 Old Gen