简体   繁体   中英

How can i implement __add__ method in parent class?

I have object-oriented programming modelling for geometric shapes. I have add method in each classes if i want to add up two geometric shapes but I have defined in each subclass. How can i implement the add method in the parent class , so that i don't to defined it for every subclasses?

import numpy as np

class Shape(object):


    def __repr__(self):
        return type(self).__name__

    def __str__(self):
        return type(self).__name__

class Circle(Shape):
    """

    """
       # constructor

    def __init__(self, radius):
        self.radius = radius
    def __add__(self, other):
        if type(other) == int:
            self.radius = self.radius + other            
        else: 
            newRadius = self.radius + other.radius
            return Circle(newRadius)
    def __radd__(self, other):
        return self.__add__(other)
    def area(self):
        return np.pi * self.radius**2

class Rectangle(Shape):
    # constructor

    def __init__(self, width,height):
        self.width , self.height = width, height
    def __add__(self, other):
        if type(other) == int:
            self.width = self.width + other  
            self.height = self.height + other  
        else: 
            newWidth = self.width + other.width
            newHeight = self.Height + other.Height
            return Rectangle(newWidth,newHeight)
    def __radd__(self, other):
        return self.__add__(other)


    def area(self):
        """
        Function to compute the area of triangle.
        """
        return self.width * self.height

This is a strange question, because it doesn't really make sense to add two circles and have the result be a new circle with the sum of the radiuses. You also have odd behaviour for adding with an int because you are changing the state of the object instead of creating a new one, like you do when adding an object.

But there is in fact a way to do this with just one method in the parent class, using some Python-specific features:

  • cls = self.__class__ is the class of the current object, which can be used to create a new object of the same class, and test if other is the right type.
  • d = self.__dict__ is a dictionary of the object's attributes.
  • The **{ ... } unpacking operator allows calling the cls constructor using a dictionary comprehension to compute the arguments.
  • I've also written a generic __repr__ which shows the state of the object, for conveniently testing examples in the REPL.

Here's an example:

class Shape:
    def __add__(self, other):
        cls = self.__class__
        d = self.__dict__
        if isinstance(other, int):
            return cls(**{ k: v + other for k, v in d.items() })
        elif isinstance(other, cls):
            return cls(**{ k: v + other.__dict__[k] for k, v in d.items() })
        else:
            raise TypeError()

    def __radd__(self, other):
        return self.__add__(other)

    def __repr__(self):
        d = self.__dict__
        return '{0}({1})'.format(
            self.__class__.__name__,
            ', '.join('{0}={1!r}'.format(k, v) for k, v in d.items())
        )

class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius

class Rectangle(Shape):
    def __init__(self, width, height):
        self.width, self.height = width, height

Examples:

>>> Circle(4) + Circle(5)
Circle(radius=9)
>>> Circle(6) + 2
Circle(radius=8)
>>> 3 + Circle(2)
Circle(radius=5)
>>> Rectangle(2, 3) + Rectangle(4, 5)
Rectangle(width=6, height=8)
>>> Rectangle(2, 3) + 1
Rectangle(width=3, height=4)
>>> 5 + Rectangle(2, 3)
Rectangle(width=7, height=8)

Note that I've changed the behaviour to always return a new object, instead of mutating the existing one.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM