繁体   English   中英

Python 如何使用 __wrapped__ 键入提示 Callable

[英]Python how to type hint a Callable with __wrapped__

在传递函数时,我通常使用typing.Callable来提示它们。

collections.abc.Callable state 的文档表明它有四种 dunder 方法:

class collections.abc.Callable

分别提供方法的类的ABC包含()、 hash ()、 len ()和call ()。

有一次,我想检查 function 上是否有__wrapped__属性。 通过使用hasattr(func, "__wrapped__")进行检查,这在运行时可以正常工作。

当 static 使用mypy进行类型检查时,它会报告: error: "Callable[..., Any]" has no attribute "__wrapped__" [attr-defined] 这对我来说很有意义,因为Callable不应该具有__wrapped__属性。

如何正确键入带有__wrapped__属性的Callable提示? 我可以做一些其他类型的提示或解决方法吗?


代码示例

我正在使用mypy==0.782Python==3.8.2

from functools import wraps
from typing import Callable


def print_int_arg(arg: int) -> None:
    """Print the integer argument."""
    print(arg)


@wraps(print_int_arg)
def wrap_print_int_arg(arg: int) -> None:
    print_int_arg(arg)
    # do other stuff


def print_is_wrapped(func: Callable) -> None:
    """Print if a function is wrapped."""
    if hasattr(func, "__wrapped__"):
        # error: "Callable[..., Any]" has no attribute "__wrapped__"  [attr-defined]
        print(f"func named {func.__name__} wraps {func.__wrapped__.__name__}.")


print_is_wrapped(wrap_print_int_arg)

Mypy 抱怨在打印语句中使用__wrapped__ 下面的技巧让 mypy 开心

def print_is_wrapped(func: Callable) -> None:
    """Print if a function is wrapped."""
    if hasattr(func, "__wrapped__"):
        wrapped_name = getattr(func, "__wrapped__").__name__
        print(f"func named {func.__name__} wraps {wrapped_name}.")

显然,简单的答案是添加# type: ignore注释。 但是,这实际上并不能解决问题,IMO。

我决定为具有__wrapped__属性的可调用对象创建一个类型存根。 基于这个答案,这是我目前的解决方案:

from typing import Callable, cast


class WrapsCallable:
    """Stub for a Callable with a __wrapped__ attribute."""

    __wrapped__: Callable

    __name__: str

    def __call__(self, *args, **kwargs):
        ...


def print_is_wrapped(func: Callable) -> None:
    """Print if a function is wrapped."""
    if hasattr(func, "__wrapped__"):
        func = cast(WrapsCallable, func)
        print(f"func named {func.__name__} wraps {func.__wrapped__.__name__}.")

mypy现在报告Success: no issues found in 1 source file

我觉得好像这是很多样板代码,并且希望得到更精简的答案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM