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

如何为动态创建的类实现动态类型提示?

问题分析与解决方案

核心原因

静态类型检查器(比如mypy、Pyright)是静态分析代码,不会执行运行时的动态逻辑。你在create()函数内部定义的TD TypedDict、动态修改的__annotations__,以及用type()创建类的过程,都是运行时才会发生的操作,类型检查器在分析代码时根本看不到这些细节,自然无法提供正确的类型提示。

可行解决方案

要让类型提示生效,必须把需要类型检查的结构暴露在静态分析能覆盖到的范围(比如模块级别),再通过类型断言告诉检查器动态创建的类符合预期结构。

步骤1:定义模块级别的类型协议和TypedDict

先在模块顶部定义好Child类需要的参数结构和属性协议:

from typing import Type, cast, Unpack, TypedDict, Protocol

class Base:
    def __init__(self, **kwargs: object) -> None:
        pass

# 模块级别定义__init__的参数结构
class ChildInitTD(TypedDict):
    first: int
    second: str

# 定义Child类应该符合的协议(包含属性和构造方法)
class ChildProtocol(Protocol):
    a: int
    b: str
    def __init__(self, **kwargs: Unpack[ChildInitTD]) -> None: ...

步骤2:修改create函数,用类型断言返回协议类型

调整create()函数,返回时用cast告诉类型检查器,动态创建的类符合ChildProtocol:

def create() -> Type[ChildProtocol]:
    def __init__(self, **kwargs: Unpack[ChildInitTD]):
        setattr(self, 'a', kwargs['first'])
        setattr(self, 'b', kwargs['second'])

    return cast(Type[ChildProtocol], type('Child', (Base,), {'__init__': __init__, '__annotations__': {'a': int, 'b': str}}))

验证效果

这样之后,类型检查器就能识别:

  • Child的构造方法必须传入first:int和second:str的关键字参数
  • Child实例的a属性是int类型,b是str类型

为什么原代码不行?

你原代码里的操作都是运行时动态修改,比如在函数内部定义TD、修改__init__.__annotations__,这些信息只有程序运行起来才存在,静态类型检查器不会执行create()函数来获取这些类型细节,所以完全无法识别。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 18:05:14