跟踪对对象实例的引用

时间:2014-11-21 04:04:56

标签: python

这或多或少跟踪类实例的数量,因为每次调用__new__时都会调用它:

class MyClass():
    def __new__(klass):
        try:
            klass.__instances = klass.__instances + 1
        except NameError:
            klass.__instances = 1
        return super(MyClass,klass).__new__(klass)

当对类的特定实例进行新引用时,是否有一个魔术方法被调用?如果没有,是否有直接的方法来实施一个?例如:

class MyClass():
    def __init__(self):
        self.__ref = 1
        print(self,"created.")
    def __new_reference(self):
        self.__ref = self.__ref + 1
        print("Reference to",self,"added.")
    def __del_reference(self):
        self.__ref = self.__ref - 1
        print("Reference to",self,"deleted.")

现在:

L1 = []
L2 = []
L1.append(MyClass()) #<MyClass object> created
L1[0].__ref          #1
L2.append(L1[0])     #Reference to <MyClass object> added.
L2[0].__ref          #2
L1.pop(0)            #Reference to <MyClass object> deleted.
L2[0].__ref          #1

编辑:

Here's the problem我以为我会尝试使用参考跟踪来解决。

我的想法是让对象A实例包含对对象B的多个(弱)引用。有一个包含所有有效B的单独列表。还列出了所有A以及(数千)。所需的行为是,当B列表中的任何一个B被移除时,如果任何对象A包含对该None的引用B B已从{{1}}列表中删除。

2 个答案:

答案 0 :(得分:2)

据我所知,没有神奇的方法可以做到这一点,但也许你可以使用sys.getrefcount()

  

返回对象的引用计数。返回的计数通常比您预期的高一个,因为它包含(临时)引用作为getrefcount()的参数。

使用您的示例:

>>> import sys
>>> class MyClass: pass
... 
>>> L1 = []
>>> L2 = []
>>> L1.append(MyClass())
>>> sys.getrefcount(L1[0])
2
>>> L2.append(L1[0])
>>> sys.getrefcount(L1[0])
3
>>> del L1[0]
>>> sys.getrefcount(L2[0])
2

答案 1 :(得分:0)

我只是想到一种简单的方法来实现这一目标,而且它对我的情况可能已经足够好了。

我所要做的就是确保每次引用时调用该对象。这并不像我希望的那样干净整洁,但它确实可以跟踪我对感兴趣的引用数量(虽然它不跟踪 >所有引用)。

这是一个代码示例来说明:

class MyClass():
    def __init__(self):
        self._ref = 1
        print(self,"created.")
    def __call__(self, new_ref=True):
        if new_ref is True: self.__new_reference()
        elif new_ref is False: self.__del_reference()
        return self
    def __new_reference(self):
        self._ref = self._ref + 1
        print("Reference to",self,"added.")
    def __del_reference(self):
        self._ref = self._ref - 1
        print("Reference to",self,"deleted.")

现在我可以这样做:

L1 = []
L2 = []
L1.append(MyClass())   #<MyClass object> created.
print(L1[0]._ref)      #1
L2.append(L1[0](True)) #Reference to <MyClass object> added.
print(L2[0]._ref)      #2
L1.pop(0)(False)       #Reference to <MyClass object> deleted.
print(L2[0]._ref)      #1

每次添加或删除它时,我都要记得调用我的特殊对象。

或者,我可以为特殊对象子类化一个特殊的容器类,该对象在添加或删除时使用适当的参数调用该对象。不确定是否值得努力做到这一点。