如何键入提示实例级函数(即不是方法)?
How to type hint an instance-level function (i.e. not a method)?
实例属性通常是 class 上的 annotated:
class Foo:
x: int
def __init__(self, x):
self.x = x
Foo(0).x
这有效并且 mypy 没有报告任何问题。但是,当实例属性是 Callable
时,mypy 开始抱怨:
from typing import Callable
class Foo:
func: Callable[[], int]
def __init__(self, func):
self.func = func
Foo(lambda: 0).func()
我收到以下错误:
test.py:11: error: Attribute function "func" with type "Callable[[], int]" does not accept self argument
Found 1 error in 1 file (checked 1 source file)
由于这个函数没有在class上定义,而是只存储在实例字典中,在属性查找期间它不会绑定到实例(简而言之:上面的代码片段有效)。所以我不明白为什么 mypy 会抱怨这个。是否有另一种方法来键入提示此类实例级函数?
这在 mypy 中目前已损坏,因为它假定您正在创建一个方法,这是相关问题 https://github.com/python/mypy/issues/708。
在 init 中键入函数工作正常,因为它不会认为它是 class 上的方法,以下代码正确通过类型检查并且 func
的类型是从范围。如果参数不可行,也可以直接键入属性赋值。
from collections.abc import Callable
class Foo:
def __init__(self, func: Callable[[], int]):
self.func = func
reveal_type(Foo(lambda: 0).func)
###OUTPUT###
file.py:7: note: Revealed type is "def () -> builtins.int"
另一个可以在问题中找到并避免在 init 中分配的解决方法是使用回调 Protocol
,如下所示:
from typing import Protocol
class FuncCallback(Protocol):
def __call__(self, /) -> int:
...
class Foo:
func: FuncCallback
def __init__(self, func):
self.func = func
这使得 func
成为一个 FuncCallback
协议,在调用时不需要任何参数,returns 成为一个 int
就像你的 Callable
.
实例属性通常是 class 上的 annotated:
class Foo:
x: int
def __init__(self, x):
self.x = x
Foo(0).x
这有效并且 mypy 没有报告任何问题。但是,当实例属性是 Callable
时,mypy 开始抱怨:
from typing import Callable
class Foo:
func: Callable[[], int]
def __init__(self, func):
self.func = func
Foo(lambda: 0).func()
我收到以下错误:
test.py:11: error: Attribute function "func" with type "Callable[[], int]" does not accept self argument
Found 1 error in 1 file (checked 1 source file)
由于这个函数没有在class上定义,而是只存储在实例字典中,在属性查找期间它不会绑定到实例(简而言之:上面的代码片段有效)。所以我不明白为什么 mypy 会抱怨这个。是否有另一种方法来键入提示此类实例级函数?
这在 mypy 中目前已损坏,因为它假定您正在创建一个方法,这是相关问题 https://github.com/python/mypy/issues/708。
在 init 中键入函数工作正常,因为它不会认为它是 class 上的方法,以下代码正确通过类型检查并且 func
的类型是从范围。如果参数不可行,也可以直接键入属性赋值。
from collections.abc import Callable
class Foo:
def __init__(self, func: Callable[[], int]):
self.func = func
reveal_type(Foo(lambda: 0).func)
###OUTPUT###
file.py:7: note: Revealed type is "def () -> builtins.int"
另一个可以在问题中找到并避免在 init 中分配的解决方法是使用回调 Protocol
,如下所示:
from typing import Protocol
class FuncCallback(Protocol):
def __call__(self, /) -> int:
...
class Foo:
func: FuncCallback
def __init__(self, func):
self.func = func
这使得 func
成为一个 FuncCallback
协议,在调用时不需要任何参数,returns 成为一个 int
就像你的 Callable
.