在为函数分配新属性时,如何抑制 mypy 中的“没有属性”错误?

Vic*_*Vic 10 python typechecking static-initialization mypy python-typing

我经常使用以下习惯用法进行静态初始化:

def compute_answer() -> int:
    if compute_answer.ret is None:
        # Do stuff that only happens the first time
        compute_answer.ret = 42
    return compute_answer.ret

compute_answer.ret = None
Run Code Online (Sandbox Code Playgroud)

但是,使用 mypy 进行类型检查会出现以下错误:

compute.py:2: error: "Callable[[], int]" has no attribute "ret"
compute.py:4: error: "Callable[[], int]" has no attribute "ret"
compute.py:5: error: "Callable[[], int]" has no attribute "ret"
compute.py:7: error: "Callable[[], int]" has no attribute "ret"
Run Code Online (Sandbox Code Playgroud)

如何抑制这些错误,尤其是本地错误(例如,仅此函数/属性)?

ale*_*ame 3

您可以使用返回自定义函数对象的装饰器Protocol。就像这样:

from typing import Any, Protocol, Optional


class ComputeAnswerProto(Protocol):
    ret: Optional[int]

    def __call__(self) -> int: ...


def compute_decorator(func: Any) -> ComputeAnswerProto:
    return func


@compute_decorator
def compute_answer() -> int:
    if compute_answer.ret is None:
        # Do stuff that only happens the first time
        compute_answer.ret = 42
    return compute_answer.ret


compute_answer.ret = None
Run Code Online (Sandbox Code Playgroud)

  • 在这一点上,mypy 似乎并没有帮助我们编写更好、更容易理解的代码,而是增加了不必要的复杂性。 (9认同)