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

Python中构造函数**kwargs的签名继承与多TypedDict适配

复用基于TypedDict的类构造函数

问题场景

我定义了如下两个TypedDict类型:

class TypeFilter1(TypedDict):
    c: str
    d: float

class TypeFilter2(TypedDict):
    e: float
    f: int

并基于它们实现了两个类,构造函数会解析**kwargs,仅保留对应TypedDict注解中的键值对,格式化为参数字符串:

class MyClass1():
    def __init__(self, **kwargs:Unpack[TypeFilter1]) -> None:
        self.filters = [f"{key}:{values}" for key, values in kwargs.items() if key in TypeFilter1.__annotations__ ]
        self.params = ' '.join(self.filters)
       
class MyClass2():
    def __init__(self, **kwargs:Unpack[TypeFilter2]) -> None:
        self.filters = [f"{key}:{values}" for key, values in kwargs.items() if key in TypeFilter2.__annotations__ ]
        self.params = ' '.join(self.filters)

示例使用:

a = MyClass1(c="hello", d=2.0) # self.params -> "c:hello d:2.0"
b = MyClass2(e=2.1, g=3) # self.params -> "e:2.1"

由于两个类逻辑完全一致,希望通过继承基类复用构造函数,但尝试泛型、Any类型等方式均未成功,请问该如何实现?若存在N个TypeFilter,又该如何处理?

解决方案

可以通过泛型基类+类变量指定TypedDict类型的方式实现复用,具体步骤如下:

1. 定义泛型基类

导入必要模块后,创建泛型基类,通过类属性接收子类对应的TypedDict类型,同时用TypeVar约束泛型类型为TypedDict子类:

from typing import TypedDict, Unpack, TypeVar, Generic

# 约束泛型变量为TypedDict的子类
T = TypeVar('T', bound=TypedDict)

class BaseFilterClass(Generic[T]):
    # 子类需重写该属性,绑定对应的TypedDict类型
    filter_type: type[T]
    
    def __init__(self, **kwargs: Unpack[T]) -> None:
        # 利用类属性获取TypedDict注解,过滤有效键值对
        self.filters = [f"{key}:{value}" for key, value in kwargs.items() if key in self.filter_type.__annotations__]
        self.params = ' '.join(self.filters)

2. 实现子类

子类仅需继承基类,并指定filter_type为目标TypedDict,无需重复编写构造函数:

class MyClass1(BaseFilterClass[TypeFilter1]):
    filter_type = TypeFilter1

class MyClass2(BaseFilterClass[TypeFilter2]):
    filter_type = TypeFilter2

3. 验证效果

使用方式与原代码完全一致,且类型提示依然有效:

a = MyClass1(c="hello", d=2.0)
print(a.params) # 输出: c:hello d:2.0

b = MyClass2(e=2.1, g=3)
print(b.params) # 输出: e:2.1

处理N个TypeFilter的情况

若存在N个TypeFilter,只需为每个TypeFilter创建对应子类,仅指定filter_type属性即可,完全复用基类逻辑。例如新增TypeFilter3:

class TypeFilter3(TypedDict):
    x: bool
    y: str

class MyClass3(BaseFilterClass[TypeFilter3]):
    filter_type = TypeFilter3

使用时逻辑一致:

c = MyClass3(x=True, y="test", z=100)
print(c.params) # 输出: x:True y:test

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 23:43:42