【问题标题】:How to correctly annotate object variable?如何正确注释对象变量?
【发布时间】:2021-09-27 03:59:33
【问题描述】:

如何正确地将对象注释为函数中的变量?示例如下:

class A():

    def funct_one(self, name: str, rec: B) -> None:
        ...

class B():
    ...

如您所见,我尝试执行 ,但弹出错误。

【问题讨论】:

  • 您必须在A 之前定义B 才能将其用作A 中的类型提示。
  • 如果需要前向引用,写成字符串:rec: "B"
  • @Barmar 或from __future__ import annotations

标签: python annotations


【解决方案1】:

发生这种情况是因为在当前版本的 Python 中,注释在解释器首次评估签名时被解析。这意味着此时值需要是可解析的。

您想要做的称为“前向引用”。为了使前向引用成为可能,Python 正在积极改变解析注释的方式,并将这项工作转移到以后所有引用都可以解析的时候。

在解析注释之前的时间里,值被存储为简单的字符串。像 mypy 这样的库或像 pycharm 这样的工具今天已经能够处理这个问题了。

所以你有三个选择:

  1. 重构以避免前向引用
  2. 定义注释时明确使用字符串
  3. 使用__future__ 模块启用未来行为。

选项 1: 重新排序类以在引用之前定义 B。这并不总是可行的,具体取决于布局。

class B:
    pass

class A:
    def funct_one(self, name: str, rec: B) -> None:
        pass

选项 2: 使用注释的字符串版本。 mypy 或 pycharm 等工具将为您解析对真实类的引用。

class A:
    def funct_one(self, name: str, rec: "B") -> None:
        pass

class B:
    pass

选项 3:(这是我的首选选项)通过导入未来的注释功能来使用延迟的注释处理。在这种模式下,我们可以轻松地在类型提示中对尚未定义的事物进行前向引用

from __future__ import annotations

class A:
    def funct_one(self, name: str, rec: B) -> None:
        pass

class B:
    pass

警告:一些进行注释处理的库依赖于旧的实现,但对于简单的代码,这可以正常工作。这最终将是默认情况下 python 的操作方式,并且不需要 __future__ 导入。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-18
    • 1970-01-01
    • 1970-01-01
    • 2014-04-11
    • 1970-01-01
    • 2012-12-05
    • 1970-01-01
    • 2021-08-16
    相关资源
    最近更新 更多