由于某些原因,无法正确键入可调用的类型。下面的代码会在Pylance和mypy中引发错误。
示例代码
所以如果所有这些不变的,协变的和反变的抛出一个异常。如何才能将Callable泛型化?
from typing import Generic, TypeVar, Any, Callable
class BaseModel:
...
class Model(BaseModel):
...
_T = TypeVar("_T")
_T_co = TypeVar("_T_co", covariant=True)
_T_contra = TypeVar("_T_contra", contravariant=True)
class Dispatcher(Generic[_T, _T_co, _T_contra]):
def add_callback(self, func: Callable[[_T], Any]) -> None:
...
def add_callback_co(self, func: Callable[[_T_co], Any]) -> None:
...
def add_callback_contra(self, func: Callable[[_T_contra], Any]) -> None:
...
def add_mod(self, mod: _T) -> None:
...
module_dispatcher: Dispatcher[BaseModel, BaseModel, BaseModel] = Dispatcher()
def call_me(model: Model) -> None:
...
module_dispatcher.add_callback(call_me) # Throws incompatibility
module_dispatcher.add_callback_co(call_me) # Throws incompatibility
module_dispatcher.add_callback_contra(call_me) # Throws incompatibility
module_dispatcher.add_mod(Model()) # This is OK类型/幽门输出
我只抱怨Callable。add_mod方法进行泛型类型推断。
/tmp/testing.py:35: error: Argument 1 to "add_callback" of "Dispatcher" has incompatible type "Callable[[MyModel], None]"; expected "Callable[[MyBaseModel], Any]"发布于 2022-06-04 12:23:36
这是因为函数的类型在它们的论点中是相反的。
func到module_dispatcher.add_callback的参数必须能够接受MyBaseModel的任何实例。
要了解原因,请注意您也可以执行module_dispatcher.add_mod(MyOtherModel()) (当然,假设是issubclass(MyOtherModel, MyBaseModel) )。现在,将使用不是MyModel实例的东西来调用MyModel。
我提出的解决办法:
def call_me(model: MyBaseModel) -> None:
...如果这不适用于您,我将需要更多地了解Dispatcher类所需的行为。
https://stackoverflow.com/questions/72499604
复制相似问题