删除对象以及在Python中对它的所有引用? [英] Delete an object and all references to it in Python?

查看:478
本文介绍了删除对象以及在Python中对它的所有引用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有一种方法可以一次删除对一个对象的所有引用?我知道那是非Python的,所以我将解释我正在尝试做的事情,也许有人知道更好的方法.

Is there a way to remove all references to an object at once? I know that's unpythonic, so I'll explain what I'm trying to do and maybe someone knows a better way.

我正在为C库的SWIG包装器编写一个面向对象的包装器.删除C对象之一的代理时,它也会删除子对象(直接在C中).我也希望在Python中触发其代理对象的删除.否则,我会遇到这样的情况:有些Python对象带有无效的指针,如果访问这些指针,这些指针将发生段错误.

I'm writing an object-oriented wrapper around a SWIG wrapper for a C library. When a proxy for one of the C objects is deleted, it also deletes child objects (directly in C). I'd like that to also trigger deletion of their proxy objects in Python. Otherwise I run into a situation where there are Python objects carrying around invalid pointers which will segfault if they're accessed.

看起来像这样:

class Parent(object):
    def __init__(self):
        self.ptr = swig.createParent()
    def __del__(self):
        swig.deleteParent(self.ptr) # also deletes children

class Child(object):
    def __init__(self, parent):
        self.ptr = swig.createChild(parent)
    def __del__(self):
        swig.deleteChild(self.ptr)

这就是我担心的情况:

p = Parent()
c = Child(parent)
del p
# accessing c.ptr now would be bad right?

推荐答案

如果我对您的理解正确,则说明您正在包装一些C代码,并且C代码具有可调用的析构函数.之后,任何使用指向C代码对象的指针的尝试都会导致致命的崩溃.

If I understand you correctly, you are wrapping some C code, and the C code has a destructor that can be called. After that, any attempt to use the pointer to the C code object causes a fatal crash.

我不确定您的确切情况,所以我将给您两个替代答案.

I am not sure of your exact situation, so I am going to give you two alternate answers.

0)如果出于某种原因可以释放C对象,并且需要确保Python包装器代码不会崩溃,则需要让Python包装器知道C对象是否可用或不是.使您的Python对象处理指针不再有效.您可能会引发Python异常,返回错误代码,或者只是使方法函数成为无操作函数,具体取决于您正在执行的操作.消失的C对象不会释放Python对象,因此您可以干净地处理它.

0) If the C object can be freed for some reason out of your control, and you need to make sure your Python wrapper code doesn't crash, you need to make the Python wrapper know whether the C object is available or not. Make your Python object handle the pointer no longer being valid. You could raise a Python exception, return an error code, or just have the method functions become no-op functions, depending on what you are doing. The C object going away doesn't free the Python object, so you can handle this cleanly.

1)如果仅在释放Python对象时释放C对象,那么您就没有问题.当Python引用超出范围时,或者您对它们调用del()时,它们不会释放Python对象;而是,他们只是减少了该对象的引用计数.当引用计数变为零时,将 then 对象释放,并且您的__del__()方法函数可以调用C代码以释放C对象.

1) If the C object is only freed when the Python object is freed, you don't have a problem. Python references, when they go out of scope or you call del() on them, do not free the Python object; they just decrement the reference count on that object. When the reference count goes to zero, then the object is freed and your __del__() method function can call into the C code to free the C object.

您可以通过运行以下代码来观察其工作原理:

You can watch how it works by running this code:

class DelTest(object):
    def __init__(self):
        print "__init__() called: object %08x created" % id(self)
    def __del__(self):
        print "__del__() called: object %08x destroyed" % id(self)

print "begin"
print "creating object, binding to name d"
d = DelTest()
print "adding reference bound to name x"
x = d
print "adding reference bound to lst[0]"
lst = []
lst.append(d)
print "deleting lst"
del(lst)
print "deleting x"
del(x)
print "deleting d"
del(d)
print "end"

以上内容的输出:

begin
creating object, binding to name d
__init__() called: object 01e4db50 created
adding reference bound to name x
adding reference bound to lst[0]
deleting lst
deleting x
deleting d
__del__() called: object 01e4db50 destroyed
end

这篇关于删除对象以及在Python中对它的所有引用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆