我想在方法上绑定函数的参数提示,但该函数是我的类属性内部的 BaseModel 子类的构造函数。
这是我的代码:
from pydantic import BaseModel
from typing import TypeVar, Type, Generic
ModelT = TypeVar("ModelT", bound=BaseModel)
class ModelMaker(Generic[ModelT]):
def __init__(self, model: Type[ModelT]) -> None:
self.model: Type[ModelT] = model
def create(self, *args, **kwargs) -> ModelT:
return self.model(*args, **kwargs)
class MyModel(BaseModel):
name: str
age: int
maker = ModelMaker(MyModel)
instance = maker.create() # i would like to get on vscode:
# (method) def create(*, name: str, age: int) -> MyModel
# and not:
# (method) def create(...) -> MyModel
我尝试使用ParamSec,但无法将ParamSec绑定为.model。init
没有经过很好的测试(在我的测试中,
pyright
抱怨它无法解析pydantic
),但看来你可以用Type[MyModel]
替换Callable[P, MyModel]
(并使MyModel
在P
中通用)将 MyModel.__init__
的签名转移到 create
。
与
from pydantic import BaseModel
from typing import TypeVar, Type, Generic, ParamSpec, Callable
P = ParamSpec('P')
ModelT = TypeVar("ModelT", bound=BaseModel)
class ModelMaker(Generic[ModelT, P]):
def __init__(self, model: Callable[P, ModelT]) -> None:
self.model: Callable[P, ModelT] = model
def create(self, *args: P.args, **kwargs: P.kwargs) -> ModelT:
return self.model(*args, **kwargs)
class MyModel(BaseModel):
name: str
age: int
def __init__(self, n: str, a: int):
self.n = n
self.a = a
maker = ModelMaker(MyModel)
reveal_type(maker.create)
我明白了
% py312/bin/pyright tmp.py
/Users/chepner/tmp.py
/Users/chepner/tmp.py:1:6 - error: Import "pydantic" could not be resolved (reportMissingImports)
/Users/chepner/tmp.py:28:13 - information: Type of "maker.create" is "(n: str, a: int) -> MyModel"
1 error, 0 warnings, 1 information
当然,这比您的原始代码更通用,因为
model
可以是返回 BaseModel
的任何可调用函数,而不仅仅是
BaseModel
本身的实例。