Callable 是无效的基类?

Sea*_*igh 6 python type-hinting mypy

有人可以解释为什么从 unparameterized 和 parameterized 继承Callable

from typing import Callable
from typing import NoReturn
from typing import TypeVar


T = TypeVar('T', str, int)
C = Callable[[T], NoReturn]


class Foo(Callable):

    def __call__(self, t: T):
        pass


class Bar(C):

    def __call__(self, t: T):
        pass
Run Code Online (Sandbox Code Playgroud)

传递给mypy时提出了两个错误FooBar

tmp.py:13: error: Invalid base class
tmp.py:19: error: Invalid base class
Run Code Online (Sandbox Code Playgroud)

Mic*_*x2a 5

这部分是因为运行时的类不能真正从函数或可调用对象继承,部分是因为您不需要显式继承来Callable指示类是可调用的。

例如,以下程序使用 mypy 0.630 按预期进行类型检查:

from typing import Callable, Union, NoReturn, List

class Foo:
    def __call__(self, t: Union[str, int]) -> NoReturn:
        pass


class FooChild(Foo): pass


class Bad:
    def __call__(self, t: List[str]) -> NoReturn:
        pass


def expects_callable(x: Callable[[Union[str, int]], NoReturn]) -> None: 
    pass


expects_callable(Foo())         # No error
expects_callable(FooChild())    # No error
expects_callable(Bad())         # Error here: Bad.__call__ has an incompatible signature
Run Code Online (Sandbox Code Playgroud)

基本上,如果一个类有一个__call__方法,则隐式地假设该类也是可调用的。