【问题标题】:How to make a type hint forward reference如何进行类型提示前向引用
【发布时间】:2016-07-04 16:05:15
【问题描述】:

我正在玩 python 的 3.5 类型提示。我想知道如何键入提示类方法的返回类型。

这就是我的想法:

>>> 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

显然它不起作用。我想一种方法是像这样做某种“前向声明”:

>>> class A():
    pass

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

但这并没有“pythonic”的感觉。人们通常如何解决这个问题?

【问题讨论】:

  • 不仅小“pythonic”,而且完全不正确 - 因为第二类中的“A”指的是第一个,现在被遮蔽的“A”类,而不是将使用的实际类。
  • @jsbueno 同意,但规范解决方案指向一个字符串,这也不是正确的类...
  • 是的,但是由于规范规定,将进行检查的工具负责从 odule 命名空间中检索字符串中命名的对象。使用字符串,该对象将是当前类(除非它被它下面的另一个类遮蔽);通过声明存根,注解中的“活动”对象将指向存根,任何检查工具都会检索存根类而不是实际类。
  • 简而言之,如果你需要像上面那样做(我已经在另一个上下文中)不要重新声明类 - 正常声明它,并使用正常的分配来添加新成员 - 比如在class A: pass\n def b(self) -&gt; A: return A()\nA.b = b
  • @jsbueno 如何应用类方法?

标签: python python-3.5 type-hinting


【解决方案1】:

前向引用当类型提示包含尚未被引用的名称时 尚未定义,该定义可以表示为字符串文字,以 稍后解决。

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 中注释的返回值是在处理类主体时带有 A 名称的对象 - 该对象是存根 class A。因此,任何在静态或运行时分析中检查A.a() 的返回值的工具都会发现它不等于A 类。

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

class A:
    pass

def a(self) -> A:
    pass

A.a = a
del a

【讨论】:

  • 从 Python 3.7 开始,现在支持前向引用,因此不再需要将其设为字符串。
猜你喜欢
  • 2016-06-17
  • 1970-01-01
  • 2017-07-28
  • 2018-05-26
  • 2021-06-21
  • 1970-01-01
  • 1970-01-01
  • 2015-03-30
  • 1970-01-01
相关资源
最近更新 更多