Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

control initialize order when Python dataclass inheriting a class

What I kown
The Python dataclass allows inheritance, either with dataclass or class. In best practice (and also in other languages), when we do inheritance, the initialization should be called first. In Python it is:

def __init__(self):
    super().__init__()
    ...

What I'm doing
Since the dataclass was introduced in Python 3.7, I am considering replace all of my classes with the dataclass. With dataclass, one of its benefits is to generate __init__ for you. This is not good when the dataclass needs to inherit a base class -- for example:

class Base:
    def __init__(self):
        self.a = 1

@dataclass
class Child(Base):
    a:int
    def __post_init__(self):
        super().__init__() 

My problem
The problem is we have to put super initialization call inside __post_init__ which in fact is called after dataclass's init.
The downside is that we lose the convention contract and the initialization disorder leads to that we can not override attributes of super classes.

It can be solved by concept of __pre_init__. I've read the document and does not see anything to do with that concept there. Am I missing something?

like image 743
WeiChing 林煒清 Avatar asked Feb 28 '19 14:02

WeiChing 林煒清


People also ask

Can a Dataclass inherit?

In this post, we will discuss how DataClasses behave when inherited. Though they make their own constructors, DataClasses behave pretty much the same way as normal classes do when inherited.

How does Dataclass work in Python?

DataClasses are like normal classes in Python, but they have some basic functions like instantiation, comparing, and printing the classes already implemented. Parameters: init: If true __init__() method will be generated. repr: If true __repr__() method will be generated.

What is __ Post_init __ Python?

Modifying fields after initialization with __post_init__ In other words, it is called after the object receives values for its fields, such as name , continent , population , and official_lang .

Can Python Dataclass have methods?

A dataclass can very well have regular instance and class methods. Dataclasses were introduced from Python version 3.7. For Python versions below 3.7, it has to be installed as a library.


1 Answers

Actually there is one method which is called before __init__: it is __new__. So you can do such a trick: call Base.__init__ in Child.__new__. I can't say is it a good solution, but if you're interested, here is a working example:

class Base:
    def __init__(self, a=1):
        self.a = a


@dataclass
class Child(Base):
    a: int

    def __new__(cls, *args, **kwargs):
        obj = object.__new__(cls)
        Base.__init__(obj, *args, **kwargs)
        return obj


c = Child(a=3)
print(c.a)  # 3, not 1, because Child.__init__ overrides a
like image 91
sanyassh Avatar answered Sep 22 '22 05:09

sanyassh