3

オブジェクトへのすべての参照を一度に削除する方法はありますか?私はそれが非パイソンであることを知っているので、私がやろうとしていることを説明し、おそらく誰かがより良い方法を知っています。

CライブラリのSWIGラッパーの周りにオブジェクト指向ラッパーを書いています。Cオブジェクトの1つのプロキシが削除されると、子オブジェクトも削除されます(Cで直接)。Pythonでプロキシオブジェクトの削除もトリガーしたいと思います。そうしないと、Pythonオブジェクトが無効なポインターを持ち歩き、アクセスされた場合にセグメンテーション違反が発生するという状況に遭遇します。

これは次のようになります。

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?
4

2 に答える 2

3

私があなたを正しく理解しているなら、あなたはいくつかのCコードをラップしていて、Cコードには呼び出すことができるデストラクタがあります。その後、Cコードオブジェクトへのポインタを使用しようとすると、致命的なクラッシュが発生します。

私はあなたの正確な状況がわからないので、私はあなたに2つの代替の答えを与えるつもりです。

0)何らかの理由でCオブジェクトを解放でき、Pythonラッパーコードがクラッシュしないようにする必要がある場合は、PythonラッパーにCオブジェクトが使用可能かどうかを通知する必要があります。Pythonオブジェクトにポインタを処理させて無効にします。何をしているかに応じて、Python例外を発生させたり、エラーコードを返したり、メソッド関数をno-op関数にしたりすることができます。CオブジェクトがなくなってもPythonオブジェクトは解放されないため、これを適切に処理できます。

1)Pythonオブジェクトが解放されたときにのみCオブジェクトが解放される場合は、問題はありません。Python参照は、スコープ外になるか、呼び出すときにdel()、Pythonオブジェクトを解放しません。そのオブジェクトの参照カウントをデクリメントするだけです。参照カウントがゼロになると、オブジェクトが解放され、__del__()メソッド関数がCコードを呼び出してCオブジェクトを解放できます。

このコードを実行すると、どのように機能するかを確認できます。

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
于 2012-04-09T03:52:29.093 に答える
0

メソッドの動作__del__()に関するメモ。

del xは直接呼び出しませんx.__del__()—前者はxの参照カウントを1つ減らし、後者はxの参照カウントがゼロに達したときにのみ呼び出されます。

したがって、削除しても、参照がなくなるまですぐに実行されるparentとは限りません。__del__これが例です。

>>> class C(object):
...     def __del__(self):
...         print "deleting object of type: %s" %self.__class__
... 
>>> class D(object):
...     def __init__(self, parent):
...         self.parent = parent
...     def __del__(self):
...         print "deleting object of type: %s" % self.__class__
... 
>>> c = C()
>>> d = D(c)
>>> del c
>>> del d
deleting object of type: <class '__main__.D'>
deleting object of type: <class '__main__.C'>

__del__のメソッドは、呼び出しのCに呼び出されることに注意してください。del d

于 2012-04-09T03:41:33.247 に答える