Python multiple inheritance, initializing from a common subclass - python

How can I make a common subclass initialize all parent classes it's inheriting from?
class Mom(object):
def __init__(self):
print("Mom")
class Dad(object):
def __init__(self):
print("Dad")
class Child(Mom, Dad):
def __init__(self):
super(Child, self).__init__()
c = Child() #only prints Mom

They are missing the super() calls in the Mom and Dad classes that are required for co-operative subclassing to work.
class Mom(object):
def __init__(self):
super(Mom, self).__init__()
print("Mom")
class Dad(object):
def __init__(self):
super(Dad, self).__init__()
print("Dad")
class Child(Dad, Mom):
def __init__(self):
super(Child, self).__init__()
c = Child() # Mom, Dad

You need to call super in Mom's __init__ as well.

Related

Not being able to inherit the logger [duplicate]

Consider the following code:
class A(object):
def __init__(self):
pass
class B(object):
def __init__(self):
self.something = 'blue'
def get_something(self):
return self.something
class C(A,B):
def __init__(self):
super().__init__()
print(self.get_something())
and then do:
c = C()
which results in something like this:
AttributeError: 'C' object has no attribute 'something'
I suppose this happens due to the constructor of B not being called when using super(). Is there a way to achieve the correct behavior with Python 3?
Superclasses should use super if their subclasses do. If you add the super().__init__() line into A and B your example should work again.
Check the method resolution order of C:
>>> C.mro()
[__main__.C, __main__.A, __main__.B, builtins.object]
This article should clear things up.
As others have mentioned, the method resolution order is key here. If you want to call multiple superclass constructors, then you will have to call them directly.
class A(object):
def __init__(self):
pass
class B(object):
def __init__(self):
self.something = 'blue'
def get_something(self):
return self.something
class C(A,B):
def __init__(self):
A.__init__(self)
B.__init__(self)
print(self.get_something())

How to get self.value from an inherited class?

I have this two classes that I needed to divide, though they share some common features. Is it possible to access first class' self.value from the second class? Please look at the pseudo code, surely more understandable then my words.
class a:
def __init__(self):
self.value = 45
class b(a):
def __init__(self):
self.other_value = #this should be self.value from class a
You need call the parent constructor first
class B(A):
def __init__(self):
super().__init__()
print(self.value)
you should call the parent constructor:
class b(a):
def __init__(self):
a.__init__(self)
#now you can use it with self.value

What is the issue with inheritance in this code?

class a(object):
def __init__(self):
self.num1=0
self.num2=0
def set1(self,score1,score2):
self.num1=score1
self.num2=score2
def show1(self):
print("num1",self.num1,"num2",self.num2)
class b(a):
def __init__(self):
super().__init__()
def set2(self):
self.sum=self.num1+self.num2
def show2(self):
print("d=",self.sum)
class c(b):
def __init__(self):
super.__init__()
def set3(self):
self.multiplication=self.num1*self.num2
def show3(self):
print("f=",self.multiplication)
objects=c()
objects.set1(1000,100)
objects.show1()
objects.set2()
objects.show2()
objects.set3()
objects.show3()
I wrote this code to work on the meaning of inheritance, but I receive:
objects=c()
File "C:\Users\user\Desktop\New folder\2.py", line 23, in __init__
super.__init__()
TypeError: descriptor '__init__' of 'super' object needs an argument
num1 and num2 are two numbers and I want to calculate sum and multiplication of them via concept of inheritance in Python.
I do not know what is the problem with.What is the problem with this code?
Thanks,
You wrote super.__init__() instead of super().__init__() in __init__ of class c.
If you are using Python 2 you will need to call super in the following way: super(ClassName, self).__init__().
You need to call super, right now its just a reference.
class c(b):
super().__init__()
The other thing is that if you wanted to make this inheritance more robust, you could pass through all args and kwargs to __init__ like so:
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
This would make your classes more flexible, and open to multiple inheritance.
I think it's how you used the super() built-in Here the doc
In your case, super need two argument: the class and an instance of the class.
In your b.__init__ the synthax will be:
super(b,self).__init__()
here the solution for your problem:
class b(a):
def __init__(self):
super(b, self).__init__()
def set2(self):
self.sum=self.num1+self.num2
def show2(self):
print("d=",self.sum)
class c(b):
def __init__(self):
super(c, self).__init__()
def set3(self):
self.multiplication=self.num1*self.num2
def show3(self):
print("f=",self.multiplication)

which Design Pattern can be used?

I have 3 classes, they inherit from parent class. A parameter in the init method of the child classes is used to define in parent to set a parameter an define how a method is called.
class Parent(object):
def __init__(self, marker):
self.executeCode(marker)
class ClassA(Parent):
def __init__(self, marker):
super(ClassA, self).__init__("class_a")
class ClassB(Parent):
def __init__(self, marker):
super(ClassB, self).__init__("class b")
class ClassC(Parent):
def __init__(self, marker):
super(ClassC, self).__init__("class c")
Which is the best pattern to use here, to make it more pythonic?

Calling a parent's parent's method, which has been overridden by the parent

How do you call a method more than one class up the inheritance chain if it's been overridden by another class along the way?
class Grandfather(object):
def __init__(self):
pass
def do_thing(self):
# stuff
class Father(Grandfather):
def __init__(self):
super(Father, self).__init__()
def do_thing(self):
# stuff different than Grandfather stuff
class Son(Father):
def __init__(self):
super(Son, self).__init__()
def do_thing(self):
# how to be like Grandfather?
If you always want Grandfather#do_thing, regardless of whether Grandfather is Father's immediate superclass then you can explicitly invoke Grandfather#do_thing on the Son self object:
class Son(Father):
# ... snip ...
def do_thing(self):
Grandfather.do_thing(self)
On the other hand, if you want to invoke the do_thing method of Father's superclass, regardless of whether it is Grandfather you should use super (as in Thierry's answer):
class Son(Father):
# ... snip ...
def do_thing(self):
super(Father, self).do_thing()
You can do this using:
class Son(Father):
def __init__(self):
super(Son, self).__init__()
def do_thing(self):
super(Father, self).do_thing()

Categories