I've been struggling to understand the details of this code for a couple of days now:
class Rectangle:
def __init__(self, length, width, **kwargs):
self.length = length
self.width = width
super().__init__(**kwargs)
def area(self):
return self.length * self.width
def perimeter(self):
return 2 * self.length + 2 * self.width
# Square inherits from Rectangle:
class Square(Rectangle):
def __init__(self, length, **kwargs):
super().__init__(length=length, width=length, **kwargs)
# Triangle doesn't inherit from any class:
class Triangle:
def __init__(self, base, height, **kwargs):
self.base = base
self.height = height
super().__init__(**kwargs)
def tri_area(self):
return 0.5 * self.base * self.height
# Pyramid inherits from square and triangle:
class Pyramid(Square, Triangle):
def __init__(self, base, slant_height, **kwargs):
self.base = base
self.slant_height = slant_height
# Adding attributes to kwargs dictionary
kwargs["height"] = slant_height
kwargs["length"] = base
super().__init__( base=base, **kwargs)
def area(self):
base_area = super().area()
perimeter = super().perimeter()
return 0.5 * perimeter * self.slant_height + base_area
def area_2(self):
base_area = super().area()
triangle_area = super().tri_area()
return triangle_area * 4 + base_area
The inheritance tree is as such:
Rectangle
\
Square Triangle
\ /
Pyramid
The MRO for the Pyramid class:
(__main__.Pyramid,
__main__.Square,
__main__.Rectangle,
__main__.Triangle,
object)
I understand the general idea behind the code, and how super().__init__ is used to pass a dictionary of variable keyword arguments to the superclass using **kwargs. The details I'm having issues with are:
- Why did we, in the
Pyramidclass, usebase=basewhen the superclass (Square) takes alengthargument? - When I do only put
super().__init__(base, **kwargs)instead ofbase=base, why does it give an error saying that init() got multiple values for argument 'length', is it because of thekwargs["length"]specified above it? If so, how does base=base solve that? - Why do we have
super().__init__(**kwargs)in Rectangle when it doesn't have a superclass? My guess is maybe to pass the kwargs to the built-inobjectbase class soTrianglecan inherit from it? But I'm not sure. - Why would
Trianglealso have a call to the base class too? It seems redundant (even removingsuper().__init__(**kwargs)from Triangle doesn't change anything).