Search code examples
pythoninheritancemetaclass

how to add values in "__init__" to the list of VALUES with the meta class


How do I add self.value 1 and self.value 2 into VALUES . this is the purpose How can I add "self.value1" and "self.value2" to the VALUES list inside the meta class

class Meta(type):
    VALUES = dict()

    def __new__(mcs, name, bases, attrs):
        for k, v in attrs.items():
            print(k, v)
        return super(Meta, mcs).__new__(mcs, name, bases, attrs)


class A(metaclass=Meta):
    def __init__(self):
        self.value1 = "Class A"


class B(metaclass=Meta):
    def __init__(self):
        self.value2 = "Class B"


class Main(A, B):
    def __init__(self):
        super(Main, self).__init__()


m = Main()
print(m.__dict__)

the output i wanted {'value1': 'Class A',"value2":"Class B"}


Solution

  • This is because when you call the super() function, it doesn't call all instances of the function, only the first one it finds. Because your class definition inherits A before it inherits B, the first class to be searched is class A. The program finds the init function inside class A so it executed that and then returns. If you were instead to write class Main(B, A):, the output would be {"value2":"Class B"}, because then class B is higher in the search order than A.

    To solve the problem you have, you would have to run all of the inherited class's init functions, for example like this:

    class Main(A, B):
        def __init__(self):
            for cls in Main.__bases__:
                cls.__init__(self)
    

    This takes a reference from each parent class from the bases attribute and calls their init directly, meaning that it is called from every parent class, not just the highest priority one. I'm not sure if this is best practice or even sensible at all but it should the problem you described.