由于某些原因,不能正确键入可调用对象。下面的代码在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
mypy/pylance输出
我只抱怨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]"
这是因为函数的类型在其实参中是逆变的。
参数func
到module_dispatcher.add_callback
必须能够取MyBaseModel
的任何实例。
module_dispatcher.add_mod(MyOtherModel())
(当然,假设是issubclass(MyOtherModel, MyBaseModel)
)。现在call_me
将以而不是MyModel
的实例来调用。
我建议的解决方案:
def call_me(model: MyBaseModel) -> None:
...
如果这对你不起作用,我将需要更多地了解Dispatcher
类所需的行为。