在 python class 中为静态方法添加类型

Add typing for a staticmethod in a python class

在 class Foo 我 link 在 class 变量中的一个静态方法到 class 之后 class与另一个交换该功能。 class 包含一些调用此可交换函数的方法。下面的代码不会产生任何 mypy 问题。

def some_function(text: str) -> None:
    print(text)

class Foo:
    _some_func: ClassVar[staticmethod] = staticmethod(some_function)

    def some_method(self, text: str) -> None:
        self._some_func(text)

if __name__ == "__main__":
    Foo().some_method("Hello World!")

现在,我正在尝试改进我的打字,所以我想使用回调协议为 Foo._some_func 实际添加打字。我创建了以下协议 class:

class SomeFuncProtocol(Protocol):
    def __call__(self, __text: str) -> None:
        ...

只要我使用 _some_func: ClassVar[SomeFuncProtocol] = some_function 它就可以工作,但我找不到使用静态方法和协议 class 进行输入的方法。我希望像下面这样的东西,但是 mypy 告诉我 staticmethod 不需要类型参数。

class Foo:
   _some_func: ClassVar[staticmethod[SomeFuncProtocol]] = staticmethod(some_function)
   ...

有人知道怎么做吗?

我有一段时间被类似的东西困住了,这是对我有用的东西:

from typing import ClassVar, Protocol

def some_function(text: str) -> None:
    print(text)

class SomeFuncProtocol(Protocol):
    def __call__(self, __text: str) -> None:
        return

class Foo:
   _some_func: ClassVar[SomeFuncProtocol] = staticmethod(some_function)

Foo._some_func('a')
Foo()._some_func('a')
Foo._some_func = some_function
Foo()._some_func = some_function  # E: Cannot assign to class variable "_some_func" via instance

上面的代码进行了类型检查(除了最后一行故意不正确)。

您不需要在类型注释中使用 staticmethod:它是一个函数(简化)将可调用函数作为参数,return 是另一个具有相同签名的可调用函数,但有明确的标志表明它不需要'接受 self。所以return类型的staticmethod是同一个callable,我们可以这样表达:

from typing import Any, Callable, TypeVar
_C = TypeVar('_C', bound=Callable[..., Any])
def staticmethod(func: _C) -> _C: ...

您可以在 playground 中尝试。