Python中通过外部对象创建嵌套类的实例时如何保留对父对象的引用?

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

通过外部对象创建嵌套类的实例时,是否可以保留对父对象的引用,而不显式地将父对象作为参数传递?

class OuterClass:
    class InnerClass:
        def get_parent_link(self):
            pass

parent_obj = OuterClass()
child_obj = parent_obj.InnerClass()
child_obj.get_parent_link()  # Here, I want to access the reference to parent_obj

请提供一个解决方案,避免在创建内部类的实例时显式传递父对象,或类似的东西,例如

child_obj = parent_obj.InnerClass(parent_obj)

我不知道该怎么做,也许你需要使用一些复杂的装饰器或元类

python metaclass python-class
1个回答
0
投票

要做到这一点,你必须经历很多繁琐的工作,而这几乎肯定是不值得的。但是您可以创建注入

__init__
的元类,它也是一个描述符,在实例上访问时部分应用该对象:

import functools

class InjectParent(type):
    def __new__(cls, name, bases, ns):
        user_init = ns.get("__init__")

        def __init__(self, parent=None,  *args, **kwargs):
            self.parent = parent
            if user_init:
                user_init(*args, **kwargs)

        return super().__new__(cls, name, bases, {**ns, "__init__":__init__})

    def __get__(self, obj, objtype=None):
        if obj is None:
            return self
        return functools.partial(self, obj)

class Outer:
    class Inner(metaclass=InjectParent):
        pass

parent = Outer()
child = parent.Inner()
orphan = Outer.Inner()

assert child.parent is parent
assert orphan.parent is None

虽然这是一个有趣的练习,但我强烈建议不要在生产代码中这样做。显式优于隐式。

注意,

parent.Inner
不再指代实际的类(尽管
Outer.Inner
指代),因此
isinstance(child, parent.Inner)
将失败。

此外,它不处理

__init__
的继承。它仅处理直接在类中定义
__init__
的情况。

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