This has probably been asked to death, but I really think this question will help someone because I really can't find a question or answer for this.
I have made an effort to boil the code down to its smallest structure (ignoring the dodgy naming)
Firstly here is the stack trace of the issue:
Traceback (most recent call last):
File "C:\xx\xx\xx\main.py", line 30, in <module>
DoSomething().method()
File "C:\xx\xx\xx\main.py", line 27, in method
self.some_class_method()
File "C:\xx\xx\xx\main.py", line 12, in some_class_method
print(self.variable)
AttributeError: 'DoSomething' object has no attribute 'variable'
Process finished with exit code 1
This is the failing code (From top to bottom: lowest level to highest level, to finally calling the highest level class(Highest being the most child)):
class ParentConfig:
def __init__(self):
pass
class SomeClass:
def __init__(self):
super().__init__()
self.variable = 'value'
def some_class_method(self):
print(self.variable)
class Config(ParentConfig, SomeClass):
def __init__(self):
super().__init__()
pass
class DoSomething(Config):
def __init__(self):
super().__init__()
pass
def method(self):
self.some_class_method()
DoSomething().method()
I can get the code to work in two ways:
One, remove 'ParentConfig' parent class
class Config(<removed>, SomeClass):
def __init__(self):
super().__init__()
pass
Two, call both __init__s separately
class Config(ParentConfig, SomeClass):
def __init__(self):
ParentConfig().__init__()
SomeClass().__init__()
pass
Now, to be clear the second 'solution' doesn't work in this example, but it does fix the issue in my program, apologies for not having a perfect example.
The main point is, the class 'DoSomething' can't use self.variable when calling the method using it.
Bonus points if someone can fix my example to work when calling the ParentConfig().__init__() and SomeClass().__init__() individually but not when using just super().__init__
I hope this is enough info. In the mean time I will work on a better example and edit this.
Edit:
TLDR on Karl Knechtels answer for newbies:
Either remove def __init__(self) from ParentClass
Or
add a super().__init__() to the def __init__(self) in ParentClass
DoSomething.__mro__will show you the order in which classes are accessed when callingsuperwith aDoSomethinginstances as the root object.ParentConfig.__init__needs to callsuper().__init__()so that it behaves when part of a diamond inheritance MRO or you can try swapping the order ofConfigbase classes soSomeClasscomes first