Reputation: 76
I would like to build a class and subclasses where the subclasses inherit some methods and from the superclass.
Nothing special so far, but I would like to be able to create subclasses depending on a parameter e.g. a = Shape(sides=3, base=2, height=12)
which should result in the same as c = Triangle(base=2, height=2)
in the sample code:
class Shape:
def __new__(cls, sides, *args, **kwargs):
if sides == 3:
print('a')
return Triangle(*args, **kwargs)
else:
return Square(*args, **kwargs)
def __init__(self, a):
self._a = a
@property
def a(self):
return self._a
class Triangle(Shape):
def __init__(self, base, height):
super().__init__(self, a='triangle')
self.base = base
self.height = height
def area(self):
return (self.base * self.height) / 2
class Square(Shape):
def __init__(self, length):
Shape.__init__(self, a='square')
self.length = length
def area(self):
return self.length * self.length
a = Shape(sides=3, base=2, height=12)
b = Shape(sides=4, length=2)
c = Triangle(base=2, height=2)
print(c.a)
print(str(a.__class__))
print(a.area())
print(str(b.__class__))
print(b.area())
Which throws an error TypeError: __new__() missing 1 required positional argument: 'sides'
.
when I do not inherit the class (do class Triangle:
) it down not throw the error but of course I cannot use the function a
anymore...
Any hints? My solutions so far were based on https://stackoverflow.com/a/60769071, https://stackoverflow.com/a/61509283 and https://www.code-learner.com/how-to-use-python-new-method-example/
One possibility is maybe the use of a Factory pattern but I really liked the idea of overwriting the new function...
Upvotes: 1
Views: 1201
Reputation: 1090
You are inheriting the Shape
class in the Triangle
& Square
classes, which will result in infinite recursive calls to __new__
of Shape
class.
Have modified your code a little with a Factory class to achieve it.
class Shape:
def __init__(self, a):
self._a = a
@property
def a(self):
return self._a
class ShapeFactory:
def __new__(cls, sides, *args, **kwargs):
if sides == 3:
print('a')
return Triangle(*args, **kwargs)
else:
return Square(*args, **kwargs)
class Triangle(Shape):
def __init__(self, base, height):
super().__init__(a='triangle')
self.base = base
self.height = height
def area(self):
return (self.base * self.height) / 2
class Square(Shape):
def __init__(self, length):
Shape.__init__(self, a='square')
self.length = length
def area(self):
return self.length * self.length
a = ShapeFactory(sides=3, base=2, height=12)
b = ShapeFactory(sides=4, length=2)
c = Triangle(base=2, height=2)
print(c.a)
print(str(a.__class__))
print(a.area())
print(str(b.__class__))
print(b.area())
Upvotes: 2
Reputation: 451
Your Triangle
class is inheriting the __new__
method of its superclass Shape
which requires the side
argument.
You could either override this method in each subclass or make a new Factory class ShapeFactory
which returns different shapes.
Upvotes: 1