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

Python不使用继承如何让子数据类访问父类实例的get_conn方法

方案实现

核心思路

放弃不稳定的inspect/traceback调用栈分析方案,采用工厂方法+Pydantic原生私有属性实现,完全不修改数据类原有__init__逻辑,也不依赖继承,适配你要求的调用习惯。


1. 关联Parent与子数据类的具体实现

借助Pydantic的PrivateAttr定义私有字段存储Parent实例引用,该字段不会被纳入数据类的参数校验、序列化逻辑,完全不影响原有数据类的使用。
再通过Parent类的__getattr__方法做动态分发,调用parent.Child()时自动将当前Parent实例注入到生成的子实例私有属性中。
示例代码如下:

from abc import ABC
from functools import partial
from pydantic import PrivateAttr
from pydantic.dataclasses import dataclass
from cached_property import cached_property

# 原有Base基类
class Base(ABC):
    @cached_property
    def _conn(self):
        raise NotImplementedError
    
    def get_conn(self):
        return self._conn

# 原有Parent类
class Parent(Base):
    @cached_property
    def _conn(self):
        # 你的专属客户端生成逻辑,仅会执行一次
        print("仅拉取一次凭证")
        return "认证客户端实例"
    
    def __getattr__(self, name):
        # 注册所有要关联的子数据类
        dataclass_map = {
            "Child": Child,
            "Toy": Toy
        }
        if name in dataclass_map:
            # 返回绑定了当前Parent实例的构造器
            return partial(self._wrap_dataclass, dataclass_map[name])
        raise AttributeError(f"'Parent' object has no attribute '{name}'")
    
    def _wrap_dataclass(self, cls, *args, **kwargs):
        instance = cls(*args, **kwargs)
        # 自动注入Parent实例到子实例私有属性
        instance._parent = self
        return instance

# 子数据类,无需继承Parent
@dataclass
class Child:
    name: str
    age: int
    # Pydantic私有属性,不会参与参数校验、序列化
    _parent: Parent = PrivateAttr()

    def get_favorite_toy(self):
        # 用当前实例绑定的Parent构造Toy,自动继承连接
        return self._parent.Toy(name="乐高", color="红色")

@dataclass
class Toy:
    name: str
    color: str
    _parent: Parent = PrivateAttr()

    def get_color(self):
        # 直接调用Parent的公共方法
        conn = self._parent.get_conn()
        print(f"使用连接 {conn} 执行逻辑")
        return self.color

2. 链路连通性验证

完全符合你期望的调用方式,所有子实例、子实例生成的其他子实例都共享同一个Parent的连接:

if __name__ == "__main__":
    parent = Parent()
    # 按理想方式创建Child实例
    child = parent.Child(name="小明", age=8)
    # 首次调用才初始化连接,仅执行一次
    print(child._parent.get_conn()) 
    # 输出:仅拉取一次凭证 \n 认证客户端实例

    # Child方法返回的Toy实例自动绑定同一个Parent
    toy = child.get_favorite_toy()
    print(toy.get_color())
    # 输出:使用连接 认证客户端实例 执行逻辑 \n 红色

方案优势

  • 完全兼容Pydantic dataclass的特性,不需要修改__init__方法,不影响原有数据类的校验、序列化逻辑
  • 连接仅初始化一次,全局复用,不会重复拉取凭证
  • 无黑魔法依赖,稳定性远高于调用栈分析方案
  • 所有子实例链路自动绑定同一个Parent实例,不需要手动注入参数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 11:15:03