当前位置: 首页 > 知识库问答 >
问题:

Python中类型注释的自我引用或前向引用[重复]

夏侯兴怀
2023-03-14

我试图弄清楚类型的自我引用是如何与python3的类型注释一起工作的——文档没有指定任何与此相关的内容。

例如:

from typing import TypeVar, Optional, Generic

T = TypeVar('T')
class Node(Generic[T]):
    left = None
    right = None
    value = None

    def __init__(
        self, value: Optional[T],
        left: Optional[Node[T]]=None,
        right: Optional[Node[T]]=None,
    ) -> None:
        self.value = value
        self.left = left
        self.right = right

此代码生成错误:

Traceback (most recent call last):
  File "node.py", line 4, in <module>
    class Node(Generic[T]):
  File "node.py", line 12, in Node
    right: Optional[Node[T]]=None,
NameError: name 'Node' is not defined

这是在使用Python3.5。1.

共有1个答案

夏知
2023-03-14

PEP 0484-类型提示-转发声明的问题解决了以下问题:

类型提示的问题是注释(根据PEP 3107,类似于默认值)在定义函数时被计算,因此注释中使用的任何名称在定义函数时都必须已经定义。一个常见的场景是类定义,其方法需要在注释中引用类本身。(更一般地说,它也可以发生在相互递归的类中。)这对于容器类型是很自然的,例如:

...

正如所写的那样,这将不起作用,因为Python的特性是,一旦类的整个主体被执行,类名就会被定义。我们的解决方案并不特别优雅,但可以完成这项工作,它允许在注释中使用字符串文字。但是,大多数情况下,您不必使用它——类型提示的大多数用法都应该引用内置类型或在其他模块中定义的类型。

from typing import TypeVar, Optional, Generic

T = TypeVar('T')
class Node(Generic[T]):
    left = None
    right = None
    value = None

    def __init__(
        self,
        value: Optional[T],
        left: Optional['Node[T]']=None,
        right: Optional['Node[T]']=None,
    ) -> None:
        self.value = value
        self.left = left
        self.right = right
>>> import typing
>>> typing.get_type_hints(Node.__init__)
{'return': None,
 'value': typing.Union[~T, NoneType],
 'left': typing.Union[__main__.Node[~T], NoneType],
 'right': typing.Union[__main__.Node[~T], NoneType]}
 类似资料:
  • 问题内容: 我试图弄清楚类型的自引用如何与python3的类型注释一起使用-文档未对此进行任何指定。 举个例子: 此代码生成错误: 这是使用Python 3.5.1 问题答案: PEP 0484-类型提示-前向声明的问题解决了以下问题: 类型提示的问题在于,在定义函数时会评估注释(根据PEP 3107 ,与默认值类似),因此在定义函数时必须已经定义了注释中使用的任何名称。常见的情况是类定义,其方法

  • 有没有办法在类中定义参数的类型,以便该类型引用自身? 例如,以下内容不会运行: 错误:

  • 我实现了一个这样的树 但是在 PyCharm 中,我得到有解决方法吗?

  • 我正在尝试创建一个自定义注释。我有这样的注释: 我有一个方面的切入点: 但我得到了这个错误,我不明白为什么: org.springframework.security.config.annotation.configuration.objectPostProcessorConfiguration':bean初始化失败;嵌套异常为java.lang.IllegalArgumentException:

  • 问题内容: 有什么办法可以从类声明中引用类名称?一个例子如下: 我有一个读取此信息并进行一些设置的元类,基类实现了一些常用的保存内容。我希望能够创建像这样的递归定义,但是到目前为止,在我的实验中,我一直无法获得想要的效果,通常会遇到“未定义计划”错误。我了解发生了什么,该类的名称不在该类的范围内。 问题答案: 我有一个元类,可以读取此信息并进行一些设置 大多数使用元类的框架都提供了一种解决此问题的