如何输入提示实例级函数(即不是方法)?

问题描述 投票:0回答:1

实例属性通常在类上注释

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)

由于该函数没有在类上定义,而仅存储在实例字典中,因此在属性查找期间它不会绑定到实例(简而言之:上面的代码片段有效)。所以我不明白为什么 mypy 会抱怨这个。是否有另一种方法来输入此类实例级函数的提示?

python python-3.x python-typing mypy
1个回答
2
投票

这目前在 mypy 中被破坏,因为它假设您正在创建一个方法,这是相关问题https://github.com/python/mypy/issues/708.

在 init 中键入函数可以正常工作,因为它不会认为它是类上的方法,以下代码正确地通过了类型检查,并且

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
协议,在调用时不需要任何参数,并返回像你的
int
一样的
Callable

© www.soinside.com 2019 - 2024. All rights reserved.