You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Python装饰器实现子类访问父类实例的间接继承?

实现subcollection装饰器:让嵌套子类访问父类实例

完全可以通过装饰器实现这个需求,无需工厂函数。核心思路是用装饰器标记子类并重写其初始化逻辑,同时让父类在访问子类时自动传递自身实例给子类。

装饰器与类的实现代码

def subcollection(cls):
    # 标记该类为子集合类
    cls._is_subcollection = True
    # 保存原始初始化方法
    original_init = cls.__init__

    def wrapped_init(self, parent_instance, *args, **kwargs):
        self.parent = parent_instance
        original_init(self, *args, **kwargs)

    # 替换子类的初始化方法,使其接收父实例
    cls.__init__ = wrapped_init
    return cls


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

    def __getattr__(self, attr_name):
        # 从父类的类属性中查找目标子类
        target_cls = getattr(self.__class__, attr_name, None)
        # 判断是否是被标记的子集合类
        if target_cls and hasattr(target_cls, '_is_subcollection') and target_cls._is_subcollection:
            # 返回一个绑定了父实例的创建函数,支持子类初始化传参
            def create_child(*args, **kwargs):
                return target_cls(self, *args, **kwargs)
            return create_child
        raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{attr_name}'")


# 用装饰器标记子类
@subcollection
class ChildClass:
    def greet(self):
        print(f"Hello from Child, parent name is {self.parent.name}")

测试验证

# 创建父类实例
parent = ParentClass("Alice")
# 创建子类实例(自动传入父实例)
child = parent.ChildClass()
# 调用子类方法,访问父类属性
child.greet()  # 输出:Hello from Child, parent name is Alice

原理说明

  1. 装饰器subcollection:给子类添加标记_is_subcollection,并重写__init__方法,让子类实例初始化时接收并保存父类实例到self.parent属性。
  2. 父类__getattr__方法:当父类实例访问嵌套的子类时,自动检测该子类是否被装饰器标记。如果是,返回一个绑定了父实例的创建函数,调用该函数时会自动把父实例传递给子类的初始化方法。
  3. 灵活性:如果子类需要额外初始化参数,直接在创建时传入即可,比如parent.ChildClass("extra_param"),参数会被传递给子类原始的__init__方法。

内容的提问来源于stack exchange,提问作者Mahdi Jadaliha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 15:31:49