Class inheritance in Python 3.7 dataclasses

前端 未结 8 769
离开以前
离开以前 2020-11-28 22:12

I\'m currently trying my hands on the new dataclass constructions introduced in Python 3.7. I am currently stuck on trying to do some inheritance of a parent class. It looks

8条回答
  •  一个人的身影
    2020-11-28 22:38

    A possible work-around is to use monkey-patching to append the parent fields

    import dataclasses as dc
    
    def add_args(parent): 
        def decorator(orig):
            "Append parent's fields AFTER orig's fields"
    
            # Aggregate fields
            ff  = [(f.name, f.type, f) for f in dc.fields(dc.dataclass(orig))]
            ff += [(f.name, f.type, f) for f in dc.fields(dc.dataclass(parent))]
    
            new = dc.make_dataclass(orig.__name__, ff)
            new.__doc__ = orig.__doc__
    
            return new
        return decorator
    
    class Animal:
        age: int = 0 
    
    @add_args(Animal)
    class Dog:
        name: str
        noise: str = "Woof!"
    
    @add_args(Animal)
    class Bird:
        name: str
        can_fly: bool = True
    
    Dog("Dusty", 2)               # --> Dog(name='Dusty', noise=2, age=0)
    b = Bird("Donald", False, 40) # --> Bird(name='Donald', can_fly=False, age=40)
    

    It's also possible to prepend non-default fields, by checking if f.default is dc.MISSING, but this is probably too dirty.

    While monkey-patching lacks some features of inheritance, it can still be used to add methods to all pseudo-child classes.

    For more fine-grained control, set the default values using dc.field(compare=False, repr=True, ...)

提交回复
热议问题