【问题标题】:Dataclass inheritance with complex fields具有复杂字段的数据类继承
【发布时间】:2021-06-12 20:28:13
【问题描述】:

我希望在 Python 中使用数据类来创建一个基类和几个派生类。这些类将包含复杂的属性,例如字典。我希望派生类只更改基类定义的字典的一部分,这可能吗?还是我最好上普通的旧课程?
代码sn -p 中显示的是当前的情况,这在代码重复方面似乎很浪费。
在此示例中,我可以定义一个接受单个参数而不是 lambda 的函数,但在现实世界的示例中,我必须为每个此类情况定义一个函数,这很麻烦。

from dataclasses import dataclass, field


@dataclass
class BaseDataClass:
    simple_field_one: int = 100
    simple_field_two: int = 200
    complex_field: dict = field(default_factory=lambda: {
        'x': 0.1,
        'y': ['a', 'b']
    })


@dataclass
class DerivedDataClass(BaseDataClass):
    simple_field_two: int = 300  # this is easy
    complex_field: dict = field(default_factory=lambda: {
        'x': 0.1,
        'y': ['a', 'c']
    })  # this is wasteful. All I changed was complex_field['y'][1]

【问题讨论】:

    标签: python python-dataclasses


    【解决方案1】:

    这可能很明显,但如果更改非常小,使用__post_init__ 应用它而不是重新定义字段可能会很方便:

    from dataclasses import dataclass, field
    
    
    @dataclass
    class BaseDataClass:
        simple_field_one: int = 100
        simple_field_two: int = 200
        complex_field: dict = field(default_factory=lambda: {
            'x': 0.1,
            'y': ['a', 'b']
        })
    
    
    @dataclass
    class DerivedDataClass(BaseDataClass):
        simple_field_two: int = 300
    
        def __post_init__(self):
            self.complex_field['y'][1] = 'c'
    

    略有不同的替代方案,以防您希望能够在初始化期间控制对complex_field 的更新:

    from dataclasses import dataclass, field, InitVar
    
    ...
    
    @dataclass
    class DerivedDataClass(BaseDataClass):
        simple_field_two: int = 300
        # having a mutable default is fine here, since its reference isn't kept around
        # and we don't change it during post_init
        complex_update: InitVar[dict] = {'y': ['a', 'c']}
    
        def __post_init__(self, complex_update):
            self.complex_field.update(complex_update)
    

    【讨论】:

      【解决方案2】:

      我以这种方式广泛使用数据类,而且它似乎工作得很好。

      然而,我所做的一个区别是让复杂字段成为他们自己的数据类(请参阅Python nested dataclasses ...is this valid?)。

      您可能需要考虑这种方法,看看它如何帮助您减少您所看到的一些冗长。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-09-17
        • 1970-01-01
        • 2011-01-27
        • 2011-12-08
        • 1970-01-01
        • 2013-05-14
        • 1970-01-01
        相关资源
        最近更新 更多