如何制作类型提示前向引用

How to make a type hint forward reference

我正在研究 python 的 3.5 类型提示。我想知道如何键入提示 class 方法的 return 类型。

这就是我的想法:

>>> class A():
    @classmethod
    def a(cls) -> A:
        pass

Traceback (most recent call last):
  File "<pyshell#24>", line 1, in <module>
    class A():
  File "<pyshell#24>", line 3, in A
    def a(cls) -> A:
NameError: name 'A' is not defined

显然它不起作用。我想一种方法是像这样做某种 "forward declaration":

>>> class A():
    pass

>>> class A():
    @classmethod
    def a(cls) -> A:
        pass

但那感觉不"pythonic"。人们通常如何解决这个问题?

Forward references When a type hint contains names that have not been defined yet, that definition may be expressed as a string literal, to be resolved later.

https://www.python.org/dev/peps/pep-0484/#forward-references

PEP 文本继续提供以下示例:

class Tree:
    def __init__(self, left: 'Tree', right: 'Tree'):
        self.left = left
        self.right = right

除了提供字符串外,您提出的解决方法还有一个问题 - 如果您这样做:

class A():
    pass

class A():
    @classmethod
    def a(cls) -> A:
        pass

在(最终的和真实的)class A 中注释的 return 值是在处理 class 正文时携带 A 名称的对象 -该对象是存根 class A。因此,任何在静态或运行时分析中检查 A.a() 的 return 值的工具都会发现它不等于 class A.

所以,如果需要解决这个问题(我曾经需要它,我忘记了上下文 - 它与注释无关 - 啊 - 我现在想起来了:它在一个自动生成的项目中Python 特定 C 库的 ctypes 包装器),方法是创建一个单一的 class,然后用赋值语句对其进行扩充。对于您的示例,那将是:

class A:
    pass

def a(self) -> A:
    pass

A.a = a
del a