Python如何键入注释返回self的方法?

标签 python type-hinting python-3.9

假设我有一个实现方法链的类:

from __future__ import annotations

class M:
    def set_width(self, width: int)->M:
        self.width = width
        return self

    def set_height(self, height: int)->M:
        self.height = height
        return self
我可以这样使用它:
box = M().set_width(5).set_height(10)
这有效,但如果我有一个子类 M3D:
class M3D(M):
    def set_depth(self, depth: int) -> M3D:
        self.depth = depth
        return self
现在我不能这样做:
cube = M3D().set_width(2).set_height(3).set_depth(5)
我在 mypy 中收到以下错误:
_test_typeanotations.py:21: error: "M" has no attribute "set_depth"; maybe "set_width"
因为 set_width()返回 M没有方法 set_depth .我已经看到建议覆盖 set_width()set_height()为每个子类指定正确的类型,但是为每个方法编写大量代码。必须有更简单的方法。
这也与特殊方法相关,例如 __enter__传统上返回 self ,所以最好有一种方法来指定它,而无需在子类中提及它。

最佳答案

这是任何使用继承的语言中的经典问题。它由语言处理不同:

  • 在 C++ 中,您将转换 set_height 的结果调用前 set_depth
  • 在 Java 中,您可以使用与 C++ 相同的转换,或者让 IDE 生成一堆覆盖,并且仅手动更改覆盖方法中的类型。

  • Python 是一种动态类型语言,因此没有强制转换指令。所以你有 3 种可能的方式:
  • 勇敢的方法:覆盖所有相关方法以调用基方法并在返回注释中声明新类型
  • 我不在乎的方式:注释控件只给出警告。如您所知,该行没有问题,您可以忽略警告
  • 不要打扰我的方式:注释在 Python 中是可选的,注释控制通常可以通过特殊注释暂停。这里知道没有问题,因此您可以安全地暂停该指令或该方法的类型控制。

  • 以下只是我的看法。
    如果可能的话,我会避免不要打扰的方式,因为如果您将在代码中留下警告,那么如果有新警告,您将不得不在每次更改后进行控制。
    我不会为了消除警告而覆盖方法。毕竟 Python 是一种动态类型语言,甚至允许鸭子类型。如果我知道代码是正确的,我会避免添加无用的代码(DRY 和 KISS 原则)
    所以我只是假设暂停注释控件的注释是出于某种原因而发明的并使用它们(我所说的在这里不要打扰我)。

    关于Python如何键入注释返回self的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66526297/

    相关文章:

    python - id 该字段是必需的 - Django 表单集中的错误

    python - 强制 eclipse 重新加载 Python 模块

    python - 是否可以在 Python 中正确键入提示 filterM 函数?

    python - 自动生成 Python 类型注释?

    pip - 我正在尝试使用 Python 3.9.0 安装 Kivy,但在我输入 : python -m pip install kivy 后出现错误

    python - 如何将数字限制在指定范围内? (Python)

    python - 在python中查找和替换多个文件中的多个字符串

    python - 哪种类型提示表示属性不能为 None?

    python - Python 3.9 是否更新了 how to type hint the function type?

    linux - 在 Ubuntu 20.04 上使用 Pip 安装 pandas_profiling 时出错