Python 嵌套数据类……这有效吗? [英] Python nested dataclasses ...is this valid?

查看:70
本文介绍了Python 嵌套数据类……这有效吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用数据类来创建嵌套数据结构,我用它来表示复杂的测试输出.

I'm using dataclasses to create a nested data structure, that I use to represent a complex test output.

以前我通过创建多个顶级数据类然后使用组合来创建层次结构:

Previously I'd been creating a hierarchy by creating multiple top-level dataclasses and then using composition:

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的定义,而不是顶层的定义.

Problem

I was wondering if there was a way of defining the classses in a self-contained way, rather than polluting my top-level with a bunch of lower-level classes. So above, the definition of Point dataclass contains the definition of Meta, rather than the definition being at the top level.

我想知道是否可以将内部(数据类)类与数据类一起使用并让一切正常工作.

I wondered if it's possible to use inner (dataclass) classes with a dataclass and have things all work.

所以我尝试了这个:

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)

这一切似乎都有效 - 打印输出都正常工作,并且对(子)成员元素的分配也有效.

This all seems to work - the print outputs all work correctly, and the assignment to a (sub) member element works as well.

您甚至可以支持嵌套元素的默认值:

You can even support defaults for nested elements:

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 的 red10.0 默认值

...prints out red and 10.0 defaults for pt2 correctly

这是实现嵌套数据类的正确方法吗?

(意思是它现在工作并不幸运,但将来可能会坏?......或者它只是模糊而不是你如何做事?......或者它只是糟糕?)

...与组合在一起的无数顶级迷你"数据类相比,它当然要简洁得多,而且易于理解和支持一百万倍.

...It's certainly a lot cleaner and a million times easier to understand and upport than a gazillion top-level 'mini' dataclasses being composed together.

...这也比尝试使用 marshmellow 或 jerry-rigging json 模式到类结构模型要容易得多.

...It's also a lot easier than trying to use marshmellow or jerry-rigging a json schema to class structure model.

...它也很简单(我喜欢)

...It also is very simple (which I like)

推荐答案

您可以只使用字符串来注释尚不存在的类:

You can just use strings to annotate classes that don't exist yet:

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 这样的静态类型检查器也尊重这种前向引用方式,这是 对类型注释的初始鼓励,所以没什么异国情调.嵌套类也解决了问题,但更难阅读,因为扁平优于嵌套.

That way, you can reorder class definitions in the way that makes most sense. Static type checkers like mypy also respect this way of forward references, which are part of the initial pep on type annotation, so nothing exotic. Nesting the classes also solves the problem but is imo harder to read, since flat is better than nested.

这篇关于Python 嵌套数据类……这有效吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆