在Python中访问父变量

时间:2011-10-15 20:16:06

标签: python class parent

我有这样的事情:

class SomeObject:
    #code to access parents MyVar

class MyClass:
    MyVar = 3

    MyObject = SomeObject()

我需要从MyVar内部访问MyObject。有什么方法可以做到吗?

谢谢!

2 个答案:

答案 0 :(得分:5)

您可以在SomeObject中存储对MyClass对象的引用。当您使用MyClass Object作为参数创建构造函数时,可以初始化引用。

class SomeObject:
    def __init__(self, reference):
         self.reference_=reference
    #code to access parents MyVar
    self.reference_.MyVar=5

class MyClass:
    MyVar = 3

    MyObject = SomeObject(self)

由于unutbu声明我的代码没有运行,因此是一个更详细的例子。

class SomeObject:
    def __init__(self):
         self.reference_=None

    def connect(self, reference):
        self.reference_=reference
    #code to access parents MyVar
    def call(self):
        self.reference_.MyVar=5

class MyClass:
    MyVar = 3
    MyObject = SomeObject()
    def connect(self):
        self.MyObject.connect(self)

if __name__ == '__main__':
    myclass = MyClass()
    myclass.connect()
    myclass.MyObject.call()
    print(myclass.MyVar)

答案 1 :(得分:0)

你必须存储对你父母的引用,但你可以自动发生这种魔法:

from weakref import ref

class MyClass(object):
    def __setattr__(self, key, value):
        self.__dict__[key] = value
        try:
            value._parent = ref(self)
        except AttributeError:
            raise TypeError('MyClass cannot have children of type ' +
                            type(value).__name__)
    def __delattr__(self, key):
        v = self.__dict__[key]
        del self.__dict__[key]
        try:
            v._parent = None
        except AttributeError:
            raise TypeError('Child of MyClass is mysteriously '
                            'missing its parent')

class SomeObject(object):
    _parent = None
    @property
    def parent(self):
        if self._parent is not None:
            return self._parent()
        return None

>>> a = MyClass()
>>> a.b = SomeObject()
>>> print a.b.parent
<__main__.MyClass at 0x8ce60f0>
>>> b = a.b
>>> del a.b
>>> print b.parent
None

通过覆盖__setattr____delattr__运算符,您可以控制子对象的父视图,并确保连接始终正确。此外,这可以避免使用笨拙的add / remove方法;你可能不小心忘记使用的方法。这会将您的对象限制为完全一个父级,但对于这些类型的模型,这通常是可取的。

最后,我建议您不要直接持有父对象的引用,而是持有弱引用。这避免了可能混淆垃圾收集器的循环引用(a保存对b的引用,a包含对{{1}}的引用。它们的引用计数永远不会转到0,所以它们不是垃圾收集的。)