如何在Python/mypy中使用动态类型作为返回类型

问题描述 投票:0回答:1

我正在尝试使用动态创建的类型作为返回类型。

代码有效,但 mypy 抛出错误。

代码片段以非常简单的方式显示了问题,但是当我在项目中使用动态返回类型时,它们是有意义的(FastAPI 用于捕获 OpenAPI 规范中的响应结构)

我遇到的问题是让 mypy 接受动态类型作为有效类型。它因

[valid-type]
错误而中断:

cpl/features/aup/api/mypy_error.py: note: In function "list_products":
cpl/features/aup/api/mypy_error.py:79: error: Variable "cpl.features.aup.api.mypy_error.PydanticProduct" is not valid as a type  [valid-type]
cpl/features/aup/api/mypy_error.py:79: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases

我已将遇到的问题浓缩到下面的代码片段中:

# creating class dynamically
Product = type("Product", (object, ), {})


# Use dynamic class as return type
def list_products() -> list[Product]:  # This gives [valid-type] error
    """
    List all products.

    :return: A list of products.
    """
    return [Product(), Product(), Product()]

任何人都可以帮我解决这个问题,必须有一种方法来解决 mypy 接受这种类型的输入。

注意: 我实际使用它的是在 FastAPI 端点中,因此实际的返回类型结构对于生成的 OpenAPI 规范有意义。

python fastapi mypy pydantic
1个回答
0
投票

像 Mypy 这样的工具会对代码执行静态分析,这意味着它们无法分析在运行时确定返回类型信息的代码。

您提到在运行时生成这些类的原因是为了避免需要手动创建许多重复的类定义。

因此,也许可以提供帮助的是

Protocol
功能,该功能在 PEP 544 中进行了解释。它允许您创建一个类来描述类型的行为,然后使用该类作为实际类型的替代。

通过定义一个描述对象保证具有的属性和方法的协议类,您可以使用该协议来注释您的函数,而不是使用动态创建的类型。

您还可以使用

@runtime_checkable
装饰器 来支持使用
isinstance
对协议进行类型缩小。

© www.soinside.com 2019 - 2024. All rights reserved.