问题描述
背景
我正在使用数据类创建嵌套的数据结构,用于表示复杂的测试输出。
以前,我是通过创建多个顶级数据类然后使用组合来创建层次结构的:
from dataclasses import dataclass
@dataclass
class Meta:
color: str
size: float
@dataclass
class Point:
x: float
y: float
stuff: Meta
point1 = Point(x=5,y=-5,stuff=Meta(color='blue',size=20))
问题
我想知道是否存在一种以独立方式定义类的方法,而不是用一堆较低级别的类来污染我的顶层。
因此,在上面,Point
数据类的定义包含Meta
的定义,而不是顶层的定义。
解决方案?
我想知道是否可以将内部(数据类)类与数据类一起使用并使所有功能正常工作。
所以我尝试了这个:
rom dataclasses import dataclass
from typing import get_type_hints
@dataclass
class Point:
@dataclass
class Meta:
color: str
size: float
@dataclass
class Misc:
elemA: bool
elemB: int
x: float
y: float
Meta: Meta
misc: Misc
point1 = Point(x=1,y=2,Meta=Point.Meta(color='red',size=5.5),misc=Point.Misc(elemA=True,elemB=-100))
print("This is the point:",point1)
print(point1.x)
print(point1.y)
print(point1.Meta)
print(point1.misc)
print(point1.Meta.color)
print(point1.misc.elemB)
point1.misc.elemB = 99
print(point1)
print(point1.misc.elemB)
这一切似乎都可以正常工作-打印输出都可以正常工作,并且对(子)成员元素的分配也可以正常工作。
from dataclasses import dataclass
@dataclass
class Point:
@dataclass
class Meta:
color: str = 'red'
size: float = 10.0
x: float
y: float
Meta: Meta = Meta()
pt2 = Point(x=10,y=20)
print('pt2',pt2)
...正确打印出pt2的red
和10.0
默认值
问题
这是实现嵌套数据类的正确方法吗?
(这意味着它现在还算运气,但是将来可能会崩溃吗?...或者它只是丑陋的,而不是您的工作方式吗?...或者这很糟糕?)
...比起组合成千上万亿个顶级“迷你”数据类,它肯定要干净得多,并且易于理解和升级一百万倍。
...比尝试使用marshmellow或将json模式绑定到类结构模型要容易得多。
...这也非常简单(我喜欢)
解决方法
您可以仅使用字符串来注释尚不存在的类:
from dataclasses import dataclass
@dataclass
class Point:
x: float
y: float
stuff: "Meta"
@dataclass
class Meta:
color: str
size: float
point1 = Point(x=5,y=-5,stuff=Meta(color='blue',size=20))
这样,您可以按照最有意义的方式对类定义进行重新排序。像mypy这样的静态类型检查器也遵循这种前向引用方式,因为它们是TUI command的一部分,因此没有任何异域。嵌套类也可以解决该问题,但更难读the initial pep on type annotation。