我正在创建一个函数,它将充当类的工厂,它的外观如下:
T = TypeVar("T")
def app_factory(app: Type[T], *args, **kwargs) -> T:
...
return app(*args, **kwargs)
class App:
def __init__(self, a: str, b: bool):
self.a = a
self.b = b
app_instance = app_factory(app=App, a="string", b=True)
是否可以根据第一个输入参数
app_factory
动态地给出a: str, b: bool
类型提示app
?换句话说,有没有办法动态地将函数的 ParamSpec 设置为等于函数输入可调用对象之一?
是的,这是可行的,因为类型检查器实现应该将
type[T]
识别为 Callable[P, T]
的子类型,其中 P
是 T
的 __new__
或 __init__
的参数类型。
from __future__ import annotations
import typing as t
if t.TYPE_CHECKING:
import collections.abc as cx
T = t.TypeVar("T")
P = t.ParamSpec("P")
def app_factory(app: cx.Callable[P, T], *args: P.args, **kwargs: P.kwargs) -> T:
return app(*args, **kwargs)
class App:
def __init__(self, a: str, b: bool) -> None:
self.a = a
self.b = b
>>> app_factory(app=App, a="string", b=True) # OK
>>> app_factory(app=App, a="string", b=1) # mypy: Argument "b" to "app_factory" has incompatible type "int"; expected "bool" [arg-type]