【问题标题】:Mypy annotation on a class decorator类装饰器上的 Mypy 注释
【发布时间】:2019-11-13 06:32:03
【问题描述】:

我在 Python 中使用类装饰器,但无法确定要为我的类提供哪种类型注释以使 mypy 开心。

我的代码如下:

from typing import Type
from pprint import pformat


def betterrepr(cls:Type[object]):
    """Improve representation of a class"""

    class improved_class(cls):  # line 12
        def __repr__(self) -> str:
            return f"Instance of {cls.__name__}, vars = {pformat(vars(self))}"

    return improved_class

我目前遇到以下 2 个错误:

myprog.py:12:错误:无效类型“cls”

myprog.py:12: 错误:无效的基类

cls 的类型应该使用什么(顺便说一句,将这个关键字用于作为参数的类是 Pythonic 吗?)?

谢谢

【问题讨论】:

  • 请注意,您可以修改 cls,而不是从它继承。
  • cls 是类的规范名称,例如作为classmethod 的第一个参数。 “[...] 'cls' 是任何已知为类的变量或参数的首选拼写,尤其是类方法的第一个参数。”来自PEP8
  • 对于只修改类而不创建新类型的典型类装饰器:Mypy 使用插件来实现这种行为。对于类装饰器,您可以使用 dataclass plugin 作为参考。对于 Pyright(Microsoft 的快速类型检查器),您可以使用 dataclass transforms

标签: python python-3.x python-decorators mypy


【解决方案1】:

使用函数参数作为基类是currently not supported by mypy。您唯一的选择是使用type: ignore 注释或base: Any = cls 之类的虚拟别名来消除错误。

即使没有注释clsmypy 也能正确推断出用betterrepr 装饰的类的类型。要记录您的装饰器返回的类类似于装饰类,请使用TypeVar

from typing import Type, TypeVar
from pprint import pformat

T = TypeVar('T')


def betterrepr(cls: Type[T]) -> Type[T]:
    """Improve representation of a class"""
    class IClass(cls):  # type: ignore
        def __repr__(self) -> str:
            return f"Instance of {cls.__name__}, vars = {pformat(vars(self))}"
    return IClass

【讨论】:

    猜你喜欢
    • 2023-03-23
    • 1970-01-01
    • 2022-09-21
    • 2021-05-09
    • 1970-01-01
    • 2021-10-22
    • 2021-11-20
    • 2022-06-19
    • 2016-09-02
    相关资源
    最近更新 更多