147

在 python 3 中,我可以创建参数并返回类型注释。例子:

class Graph:
    def __init__(self, V: int, E: int, edges: list):
        pass

    @classmethod
    def fromfile(cls, readobj: type(sys.stdin)):
        pass

    def V(self) -> int:
        pass

    def E(self) -> int:
        pass

问题是我无法使用当前类(Graph)的返回类型进行注释,该类尚未定义。例子:

class Graph:
   def reverse(self) -> Graph:
       pass

此代码有错误

def reverse(self) -> Graph:
NameError: name 'Graph' is not defined

这些注释对于记录和允许 IDE 识别参数和返回类型都非常有用 => 启用自动完成

UPD:所以我想这要么是不可能的,要么需要一些我不喜欢的 hack,所以我决定使用def reverse (self) -> 'Graph': 可以理解的文档,尽管违反了规则。缺点是它不适用于 IDE 自动完成功能。

4

2 回答 2

130

在 python-3.7 中,此问题已通过在函数定义时不评估注释来解决。相反,它们__annotations__以字符串形式保存。这称为注释的延迟评估,在PEP 563中引入。

另请注意:

弃用政策

从 Python 3.7 开始,需要__future__导入才能使用所描述的功能。不会发出警告。

在 Python 3.8 中,aPendingDeprecationWarning由编译器在没有__future__ 导入的模块中存在类型注释的情况下引发。

从 Python 3.9 开始,警告变为DeprecationWarning.

在 Python 4.0 中,这将成为默认行为。不再支持使用与此 PEP 不兼容的注释。

这是一个例子:

In [7]: from __future__ import annotations

In [8]: class C:
   ...:     def func(cls, arg:str) -> C:
   ...:         pass
   ...:     

In [9]: c = C()
于 2018-04-17T07:36:05.613 回答
84

所以现在过了一段时间,我可以说我做出的决定是使用-> 'Graph'而不是-> Graph. 它不会使我的 IDE (PyCharm) 能够以这种方式识别类型,但它对于文档目的来说已经足够好了。

我可以使用的另一个可能的解决方案是在运行时更改注释,但这并不能解决文档的问题——你不会想在源代码中间的某个地方寻找类型声明......

该问题的根源在于在实际定义类之前识别类对象。这在python中根本不可能做到。

于 2013-07-08T21:04:52.020 回答