如果我有一个"工厂"方法,用一个类的类型和相关的参数来创建一个资源,有没有办法对参数进行静态分析?

from typing import Type

from pydantic import BaseModel

class Res(BaseModel):
    f: int
    class Config:
        extra = "forbid"


def factory[T](resource_type: Type[T], **kwargs) -> T:
    return resource_type(**kwargs)


factory(Res, f=3) # no problem!
factory(Res, f=3, g=4) # ValidationError, g is not allowed.

这在运行时按预期工作.我希望pyright静态地注意到,对于Res,g不是一个有效的参数.

这有可能吗?我正朝ParamSpecs的方向看,但它还没有帮助.

def factory[T, **P](resource_type: Type[T], *args: P.args, **kwargs: P.kwargs) -> T:
    return resource_type(**kwargs)
factory(Res, f=3) # says: Param spec "P@factory" has no bound value

推荐答案

typing.ParamSpec应该是个不错的 Select .错误消息说明了一切:参数规范没有绑定到任何可调用的对象.将签名从type[T]更改为Callable[P, T].

from typing import Callable, ParamSpec, TypeVar, reveal_type

from pydantic import BaseModel

T = TypeVar("T", bound=BaseModel)
P = ParamSpec("P")


class Res(BaseModel):
    f: int

    class Config:
        extra = "forbid"


def factory(resource_type: Callable[P, T], *args: P.args, **kwargs: P.kwargs) -> T:
    return resource_type(*args, **kwargs)


reveal_type(factory(Res, f=3))  # Revealed type is "Res"

Python-3.x相关问答推荐

网站抓取:当我使用Chrome DevTools中的网络选项卡时,找不到正确的URL来提供我想要的数据

如何在matplotlib中显示次要刻度标签

为什么我无法在django中按月筛选事件?

如何使用Selenium从网站下拉菜单中获取值列表?

如何获取实例化 `types.GenericAlias` 的下标类?

将值从函数传递到标签

Pandas groupby 然后 for each 组添加新行

pytorch 中 mps 设备的 manual_seed

如何使用 Selenium by class_name 从大学橄榄球数据中抓取图像 url 列表

Semaphore信号量 Python 的工作原理

为什么不切换到 Python 3.x?

sys.stdin.readline() 读取时没有提示,返回 'nothing in between'

if 语句中冒号的语法错误

Python3 的超级和理解-> TypeError?

将 args、kwargs 传递给 run_in_executor

如何在继承的数据类中创建可选字段?

Pyodbc:登录超时错误

每次启动 Google Colab 时都必须安装所需的软件包吗?

Selenium Python - 处理没有这样的元素异常

尾部斜杠的 FastAPI 重定向返回非 ssl 链接