Python对象层次结构;引用所有者实例?

时间:2012-03-20 12:01:14

标签: python oop class object relationship

是否有没有神奇的python方法来访问其中包含对当前self的引用的类的实例? 即:

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

    def say_hi(self):
        print "Hi"

class B(object)
    def __init__(self):
        __get_owner_ref__.say_hi()

A()

get_owner_ref 是不存在的神奇子弹。 python中是否有针对此行为的功能?

是的我知道我可以将引用传递给构造函数,但我正在寻找更优雅的解决方案。

5 个答案:

答案 0 :(得分:3)

不,你必须做这样的事情

class A(object):
    def __init__(self):
        self.B = B(parent=self)

    def say_hi(self):
        print "Hi"

class B(object)
    def __init__(self, parent):
        self.parent = parent   # you don't need to do this, but it might be a good idea
        parent.say_hi()

A()

答案 1 :(得分:2)

不,没有好办法做到这一点。将引用传递给初始化程序。

为了排除问题,在大多数情况下,可能通过检查堆栈来启发式地找到所有者,例如在this question中。但它将是脆弱的,错误的并且难以理解。 它违背了“显式>隐含”的哲学。

答案 2 :(得分:2)

据我所知,这样的功能不存在。此外,将其作为对构造函数的引用传递并调用self.parent.say_hi()更加明确且(确实)优雅。显式优于隐式或使用魔术语言功能。

答案 3 :(得分:2)

从技术上讲,您可以使用sys._getframe

class B(object):
    def __init__(self):
        import sys
        a = sys._getframe(1).f_locals['self']
        a.say_hi()

但你不应该这样做。它必然会导致混淆,打破新的Python实现,会使调试复杂化,并且容易中断。
sys._getframe中列出了say_hi的原因。

而是将引用传递给父对象,或传递给{{1}}方法。

答案 4 :(得分:1)

在第二个想法中,你所寻找的东西非常类似于descriptors。考虑:

class Agent(object):
    def __get__(self, obj, objtype):
        print 'Agent %s called from %s ' % (id(self), obj.name)

class X(object):
    agent = Agent()

    def __init__(self, name):
        self.name = name

a = X('Foo')
a.agent

b = X('Bar')
b.agent

这里agent附加到两个不同的实例,并且“知道”每次实例想要与他交谈。