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())
Related
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())
class A:
def __init__(self):
pass
class B(A):
pass
class C(A):
def __init__(self):
pass
print(hasattr(B, '__init__')) # True
print(hasattr(C, '__init__')) # True
How to check if derived class has its own __init__ defined in Python? In the code above, only C has an __init__ definition, but B also has an __init__ attribute by inheritance. Is there a way to distinguish them?
You can use the __dict__ of a class
class A:
def __init__(self):
pass
class B(A):
pass
class C(A):
def __init__(self):
pass
print(C.__dict__.__contains__('__init__'))
print(B.__dict__.__contains__('__init__'))
This also works and looks cleaner.
print('__init__' in C.__dict__)
print('__init__' in B.__dict__)
Even more cleaner
print('__init__' in vars(C))
print('__init__' in vars(B))
Gives output
True
False
You could just compare the two:
B.__init__==A.__init__
True
C.__init__==A.__init__
False
i have a little question that is discouraging me i have this portion of code:
class A(object):
def __init__(self):
self.variable = "Hello World!!!"
class B(A):
def __init__(self):
self.A = A()
self.inherited = self.A.variable
the thing is that i have a bunch of variables on class A that i don't want to instantiate and declare on class B one by one
is there a way to improve the code?
You are using a mix of composition and inheritance. It seems like you want to exclusively use composition:
class A(Object):
def __init__(self):
self.c = C()
self.e = E()
class B(Object):
def __init__(self):
self.c = C()
self.d = D()
Where C, D, and E are components that group variables and methods together. Now A and B only share the component of C. You should look for more complete composition tutorials
Edit: Actually just double checking it looks like your just confused about instantiating super class variables. Other answers correctly addressed this with super
You are misunderstanding two concepts.
For example, you are trying to do both composition and inheritance.
class A(Object):
def __init__(self):
self.variable = "Hello World!!!"
class B(A):
def __init__(self):
self.A = A()
self.inherited = self.A.variable
When you do this, you are saying, "Make B also an A object." In other words, the following works:
class A(object): # can omit this (object) in python3
def __init__(self):
self.value_from_a = 'Im from A!'
class B(A):
def __init__(self):
super().__init__()
self.value_from_b = 'im a bbbbb!'
b = B()
print(b.value_from_a)
print(b.value_from_b)
So, in your case the way to do this is to not try to make an A both the base as well as part of B.
Note if you are using Python2 the above syntax will be slightly different.
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)
I have been searching an answer to my question but could not hit the related answer.
Basically i am trying to call a variable from a Class A thats actually GUI to another Class B my code goes like this:
class CLASSA(wx.Frame):
def Method(self):
self.Var = anyvalue
import CLASSA
class CLASSB():
def __init__(self):
self.Var = CLASSA().Method.Var
i have tried as above but its not working out. Isn't it possible to carry out as mentioned ?
At the very least, you need to actually call CLASSA.Method first:
class CLASSB():
def __init__(self):
self.Var = CLASSA().Method().Var
in order for the Var attribute of the CLASSA object to be initialized.
You do not give enough detail to know if Method is necessary. You could, for instance, simply initialize Var in CLASSA.__init__.
# With recommended capitalization
class A(wx.Frame):
def __init__(self):
self.var = any value
class B(object):
def __init__(self):
sef.var = A().var
It's also possible that B should be a subclass of A, in which case B simply inherits var from A:
>>> class B(A):
... pass
>>> print B().var
anyvalue