创建具有自引用类型提示的递归数据类

Posted

技术标签:

【中文标题】创建具有自引用类型提示的递归数据类【英文标题】:Create recursive dataclass with self-referential type hints 【发布时间】:2021-12-16 12:18:32 【问题描述】:

我想用 Python 编写一个数据类定义,但不能在声明中引用同一个类。

我主要要实现的是这个嵌套结构的类型化,如下图:

 @dataclass
 class Category:
     title: str
     children: [Category] # I can't refer to a "Category"
  
 tree = Category(title='title 1', children=[
     Category('title 11', children=[]),
     Category('title 12', children=[])
 ])

【问题讨论】:

【参考方案1】:

选项 #1

您可以将类名包装在一个字符串中,以便转发声明注解:

from dataclasses import dataclass
from typing import List


@dataclass
class Category:
    title: str
    children: List['Category']

选项 #2

您可以包含__future__ 导入,以便默认情况下所有注释向前声明,如下所示。在这种情况下,您还可以在 Python 3.7 及更高版本中消除 typing 导入并使用新样式的注释。

from __future__ import annotations

from dataclasses import dataclass


@dataclass
class Category:
    title: str
    children: list[Category]

【讨论】:

关于选项 #2 的警告:来自PEP 563 的类型提示的“新”样式被推迟成为 Python 3.10 的默认样式,因为另一个提议 PEP 649 指出了它的一些缺点,并提供了一个略有不同的解决方案。 PEP 649 似乎最终可能会被采用,但目前尚不清楚过渡计划是什么。它应该为像这样的前向引用提供相同的好处,但它可能需要不同的 __future__ 导入才能启用。 一个很好的观点!我不知道 PEP 649,但这肯定是一个值得跟踪的提案。我特别赞成 PEP 563 引入的后一种方法,IMO 是解决上述递归注释问题的完美用例。

以上是关于创建具有自引用类型提示的递归数据类的主要内容,如果未能解决你的问题,请参考以下文章

Java 引用数据类型(类)

java引用数据类型(类)

JAVA-基础-引用数据类型(类)

JavaScript 引用类型

添加服务引用时出错:类型是不支持的递归集合数据协定

c++ 创建类的实例作为引用类型