如何在Python/mypy中使用动态类型作为返回类型?
解决动态创建类作为返回类型时的mypy [valid-type]错误
问题原因
mypy会将通过type()动态创建的Product识别为普通变量,而非合法类型,因此抛出valid-type错误,但代码本身可正常运行。
方法1:使用类型别名标记(Python 3.10+)
通过typing.TypeAlias明确告知mypy,动态创建的变量是一个类型别名,让类型检查器认可其作为类型的合法性:
from typing import TypeAlias # 动态创建类 Product = type("Product", (object, ), {}) # 标记为类型别名 Product: TypeAlias = Product def list_products() -> list[Product]: """列出所有产品。""" return [Product(), Product(), Product()]
方法2:用TYPE_CHECKING分支分离类型检查与运行时逻辑
在TYPE_CHECKING代码块中定义一个仅供mypy识别的假类,运行时则使用动态创建的类,既满足mypy的类型检查要求,又不影响FastAPI生成OpenAPI规范的动态需求:
from typing import TYPE_CHECKING if TYPE_CHECKING: # 仅用于mypy类型检查,运行时不会执行 class Product: pass else: # 运行时动态创建实际使用的类 Product = type("Product", (object, ), {}) def list_products() -> list[Product]: """列出所有产品。""" return [Product(), Product(), Product()]
如果动态类包含属性,还可以在假类中定义对应属性,让mypy提供更准确的类型提示:
from typing import TYPE_CHECKING if TYPE_CHECKING: class Product: name: str price: float else: # 动态创建带属性的类 Product = type("Product", (object, ), {"name": "", "price": 0.0})
方法3:临时忽略mypy错误(不推荐)
若仅需快速绕过错误,可在报错行添加注释,但此方法会丢失该位置的类型检查能力:
def list_products() -> list[Product]: # type: ignore[valid-type] """列出所有产品。""" return [Product(), Product(), Product()]
内容的提问来源于stack exchange,提问作者Jakob Simon-Gaarde
相关产品推荐
相关产品推荐

