How to initialize one parent at a time in multiple inheritance? - python

Suppose I have the following class inheriting from classes A and B:
class A:
def __init__(self):
self.x = 2
class B:
def __init__(self,u):
self.y = u + 2
class C(A,B):
def __init__(self):
#self.y should be 4 here
How do I initialize B only after initializing A? Using super(C,self).__init__() doesn't let me use attributes of A into B.

You don't HAVE to use super.
class A:
def __init__(self):
self.x = 2
class B:
def __init__(self,u):
self.y = u + 2
class C(A,B):
def __init__(self):
A.__init__(self)
B.__init__(self, self.x)
Now, that does mean some pretty tight coupling, in that C has to be way too aware of what A.__init__ does.

Just do this:
class A:
def __init__(self):
print("A was initialized")
self.x = 2
def getX(self):
return self.x
class B:
def __init__(self, u):
print("B was initialized")
self.u = u +2
class C(A,B):
def __init__(self, **kw):
A.__init__(self)
B.__init__(self, self.getX())

Alternatively, with super:
class A:
def __init__(self):
self.x = 2
class B:
def __init__(self,u):
self.y = u + 2
class C(A,B):
def __init__(self):
super().__init__()
super(A, self).__init__(self.x)

If you want to pass attributes in between classes use something like a return statement. Then in your B class use whatever the A class returned.

Related

Inheriting from multiple classes

class One:
def __init__(self):
self.one = 1
class Two:
def __init__(self):
self.two = 2
class Three(One, Two):
def __init__(self):
self.three = 3
super().__init__()
obj = Three()
print(obj.one)
print(obj.two)
print(obj.three)
i am currently self learning OOP, i am having a hard time understanding why the object was able to print the attribute from Class One but not also the one from Class Two despite me using the super function, the error raised is AttributeError: 'Three' object has no attribute 'two'. How do we inherit from multiple classes?
super().__init__() in Three will only refer to the first class in Method Resolution Order. In order to call all the __init__, you'd need to do super() in all of them:
class One:
def __init__(self):
self.one = 1
super().__init__()
class Two:
def __init__(self):
self.two = 2
super().__init__()
Or, if you don't want to / can't modify parent class signatures, you refer to the classes directly instead of using super, so they will all be called regardless of MRO:
class Three(One, Two):
def __init__(self):
self.three = 3
One.__init__()
Two.__init__()
class One:
def __init__(self):
self.one = 1
super().__init__()
class Two:
def __init__(self):
self.two = 2
super().__init__()
class Three(One,Two):
def __init__(self):
self.three = 3
super().__init__()
obj = Three()
print(obj.one)
print(obj.two)
print(obj.three)
use super().__init__method in every class.
if you dont want to use it. you can call init methods of class one and class two in init method of class three.

How to access the stored array in class

I want to access the array i have filled throughout the for loop,however what i get it is still empty array when call fill_particles().particles, is there any way to get rid of this problem? here is my code.
class particle(object):
def __init__(self,x,y,z):
self.x=x
self.y=y
self.z=z
class fill_particles():
def __init__(self):
self.particles=[]
def fill(self):
for i in range(5):
self.particles.append(particle(i,i+1,i+2))
You need to instantiate the class and call fill(). Here's a working example, along with extra functions for display purposes:
class Particle(object):
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
def __repr__(self):
return f'Particle(x={self.x}, y={self.y}, z={self.z})'
class Particles:
def __init__(self):
self.particles = []
def fill(self):
for i in range(5):
self.particles.append(Particle(i, i + 1, i + 2))
def __repr__(self):
return f'Particles({self.particles!r})'
particles = Particles()
print(particles)
particles.fill()
print(particles)
Output:
Particles([])
Particles([Particle(x=0, y=1, z=2), Particle(x=1, y=2, z=3), Particle(x=2, y=3, z=4), Particle(x=3, y=4, z=5), Particle(x=4, y=5, z=6)])

reusing a variable defined in a python class

Let's say I define a class. I have a fun method, where I create self.x. I want to use self.x in a different method (reuse). How could I do that? Because I tried what I wrote and didn't work. Thanks!
class test:
def __init__(self,t):
self.t = t
def fun(self):
self.x = self.t+1
def reuse(self):
self.y = self.x
You need to create all the variables in the __init__ method.
Try this:
class test:
def __init__(self,t):
self.t = t
self.x = 0
self.y = 0
def fun(self):
self.x = self.t+1
def reuse(self):
self.y = self.x

How to use `super` in multiple inheritance?

Let suppose we have defined two classes:
class A():
def __init__(self):
self.a = 0
class B():
def __init__(self):
self.b = 0
Now, we want to define a third class C that inherits from A and B:
class C(A, B):
def __init__(self):
A.__init__(self) # how to do this using super()
B.__init__(self) # how to do this using super()
You did not specify whether you are Python 2 or Python 3 and it matters as we shall see. But either way, if you will be using super() in a derived class to initialize the base classes, then the base classes must use super() also. So,
For Python 3:
class A():
def __init__(self):
super().__init__()
self.a = 0
class B():
def __init__(self):
super().__init__()
self.b = 0
class C(A, B):
def __init__(self):
super().__init__()
For Python 2 (where classes must be new-style classes) or Python 3
class A(object):
def __init__(self):
super(A, self).__init__()
self.a = 0
class B(object):
def __init__(self):
super(B, self).__init__()
self.b = 0
class C(A, B):
def __init__(self):
super(C, self).__init__()

Python 3x class methods

I'm currently learning the basics of classes, and I came up with some basic code as follows:
class shape(object):
def __init__(self, num_sides, type):
self.num_sides = num_sides
self.type = type
class square(shape):
def __init__(self, side_length):
self.num_sides = 4
self.type = 'regular quadrilateral'
self.side_length = side_length
def perim():
return side_length * 4
def area():
return side_length ** 2
class circle(shape):
def __init__(self, radius):
self.num_sides = 1
self.type = 'ellipsis'
self.radius = radius
Now, when I type the following:
shape1 = square(5)
shape1.perim()
I get the following output:
<bound method square.perim of <__main__.square object at 0x0000000003D5FB38>>
What is this? How can I get python to actually return the perimeter of the square?
Also, I have another question:
Do any class methods exist other than __init__() and __str__()? If so, can you please list them so I can go off and research them?
as shown, you are going to have some problems with this. If you are trying to have circle and square be subset set classes of shape, then the two sub classes need to be indented. Also, on class circle and square, you really do not need the (shape). also note the things I commented out as not needed.
This does not come out as I am posting it. the class shape (object):does not show up and the subclasses are not indented and I can not seem to make it show up
class shape(object):
def init(self, num_sides, type):
#self.num_sides = num_sides
self.type = type
class square:
def __init__(self, side_length):
#self.num_sides = 4
#self.type = 'regular quadrilateral'
self.side_length = side_length
def perim(self):
return self.side_length * 4
def area(self):
return self.side_length ** 2
class circle:
def __init__(self, radius):
#self.num_sides = 1
#self.type = 'ellipsis'
self.radius = radius
def area (self):
return 3.14 * self.radius ** 2
shape2 = circle (5)
print ('test of circle: ',shape2.area ())
shape1 = square(5)
print('test of square: ', shape1.perim())
Two things, indentation of the init of shape and add self. to the perim and area methods.
class shape(object):
def __init__(self, num_sides, type):
self.num_sides = num_sides
self.type = type
class square(shape):
def __init__(self, side_length):
self.num_sides = 4
self.type = 'regular quadrilateral'
self.side_length = side_length
def perim(self):
return self.side_length * 4
def area(self):
return self.side_length ** 2
class circle(shape):
def __init__(self, radius):
self.num_sides = 1
self.type = 'ellipsis'
self.radius = radius
shape1 = square(5)
print( shape1.perim())
Access instance variable with self
class square(shape):
def __init__(self, side_length):
self.num_sides = 4
self.type = 'regular quadrilateral'
self.side_length = side_length
def perim(self):
return self.side_length * 4
def area(self):
return self.side_length ** 2

Categories