通过外部对象创建嵌套类的实例时,是否可以保留对父对象的引用,而不显式地将父对象作为参数传递?
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)
。
我不知道该怎么做,也许你需要使用一些复杂的装饰器或元类
要做到这一点,你必须经历很多繁琐的工作,而这几乎肯定是不值得的。但是您可以创建注入
__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__
的情况。