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

问题描述 投票:0回答:5

是否没有神奇的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 中有这种行为的功能吗?

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

python oop class object relationship
5个回答
4
投票

不,你必须做这样的事情

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()

2
投票

您正在寻找的内容与描述符非常相似。考虑:

    class Agent(object):
        def __get__(self, obj, objtype):
            print f'Agent {id(self)} called from {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
附加到两个不同的实例,并且每次“知道”哪个实例想要与他交谈。


2
投票

不,没有好的方法可以做到这一点。将引用传递给初始化器。

为了排除问题,在大多数情况下可能可以通过检查堆栈来启发式地找到所有者,就像这个问题中那样。但它会很脆弱、有缺陷并且难以理解。 并且它违背了“显式>隐式”的哲学。


2
投票

据我所知,这样的功能不存在。此外,将其作为构造函数的引用传递并调用

self.parent.say_hi()
更加明确且(确实)优雅。显式优于隐式或使用神奇的语言功能。


2
投票

从技术上讲,您可以使用

sys._getframe

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

但是你不应该这样做。它必然会导致混乱,在新的 Python 实现上会中断,会使调试复杂化,并且很容易中断。

sys._getframe
被列在 5 年的糟糕想法中是有原因的。

相反,将引用传递给父对象或

say_hi
方法。

© www.soinside.com 2019 - 2024. All rights reserved.