I've been learning Python on Codecademy, and I'm quite confused. I can't figure out how to refer to member variables (I hope that's what they're called). Here's a piece of code I wrote to demonstrate my confusion:
class Triangle(object):
number_of_sides = 3
def __init__(self, angle1, angle2, angle3):
self.angle1 = angle1
self.angle2 = angle2
self.angle3 = angle3
def check_angles(self):
return self.angle1 + self.angle2 + self.angle3 == 180
class Equilateral(Triangle):
angle = 60
def __init__(self):
self.angle1 = self.angle
self.angle2 = self.angle
self.angle3 = self.angle
So in the Equilateral subclass, angle1, angle2, angle3, aren't included as parameters of __init__. However, in the code below, __init__ re-initializes model, color, and mpg. Why is this? Shouldn't it just be inherited just like in the above code with the Equilateral subclass? I don't understand why they were written differently.
class Car(object):
condition = "new"
def __init__(self, model, color, mpg):
self.model = model
self.color = color
self.mpg = mpg
def display_car(self):
print "This is a %s %s with %s MPG." %(self.color, self.model, str(self.mpg))
def drive_car(self):
self.condition = "used"
class ElectricCar(Car):
def __init__(self, model, color, mpg, battery_type):
self.model = model
self.color = color
self.mpg = mpg
self.battery_type = battery_type
However, in the code below, init re-initializes model, color, and mpg. Why is this?
Because the author of ElectricCar wants the user to be able to initialize ElectricCar from with four parameters.
ec = ElectricCar('xyz-500', 'blue', 0.5, 'boxy')
However, they should have passed on the arguments to the base class' __init__ method:
class ElectricCar(Car):
def __init__(self, model, color, mpg, battery_type):
super(ElectricCar, self).__init__(model, color, mpg)
self.battery_type = battery_type
In the case of EquilateralTriangle, all the angles are the same and must be 60 degrees, so it would make no sense to be able to initialize such an object from three user-provided angles.
The same comment about the base class' __init__ applies:
class Equilateral(Triangle):
angle = 60
def __init__(self):
super(Equilateral, self).__init__(Equilateral.angle,
Equilateral.angle,
Equilateral.angle)
Also note that it makes little sense to initialize Triangle from three angles, if you're talking about the kind of space where the inner angles of a triangle add up to 180 degrees (or any fixed number). It would make more sense to pass two angles only.
Both implementations seem to be slightly off. In Python a superclass' __init__() is not automatically called. You must do so explicitly.
Shouldn't it just be inherited just like in the above code with the Equilateral subclass?
When an instance of Equilateral is created, Triangle.__init__() is never called in the above implementation. There is no automatic initializer inheritance (this would violate PEP 20: "Explicit is better than implicit").
Equilateral probably should better read:
class Equilateral(Triangle):
angle = 60
def __init__(self):
super(Equilateral, self).__init__(self.angle, self.angle, self.angle)
Same thing with ElectricCar:
class ElectricCar(Car):
def __init__(self, model, color, mpg, battery_type):
super(ElectricCar, self).__init__(model, color, mpg)
self.battery_type = battery_type
I don't understand why they were written differently.
That question is hard to answer. The author either did not properly understand how Python's inheritance works or he/she had an explicit reason to not call the super class initializer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With