我如何在父类中实现__add__方法?

时间:2019-12-02 20:54:18

标签: python python-3.x oop

我有几何形状的面向对象编程模型。如果要添加两个几何形状,但在每个子类中都有定义,则我在每个类中都有 add 方法。 如何在父类中实现 add方法,这样就不必为每个子类都定义它了?

none

1 个答案:

答案 0 :(得分:1)

这是一个奇怪的问题,因为添加两个圆并使其成为半径总和的新圆并没有多大意义。添加int的行为也很奇怪,因为您正在更改对象的状态,而不是像添加对象时那样创建新对象。

但是实际上,有一种方法可以使用父类中的一种方法,使用某些特定于Python的功能来实现此目的:

  • cls = self.__class__是当前对象的类,可用于创建相同类的新对象,并测试other是否是正确的类型。
  • d = self.__dict__是对象属性的字典。
  • **{ ... }拆包运算符允许使用字典理解来调用cls构造函数以计算参数。
  • 我还编写了一个通用的__repr__来显示对象的状态,以便于在REPL中方便地测试示例。

这是一个例子:

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

示例:

>>> 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)

请注意,我已将行为更改为始终返回一个新对象,而不是对现有对象进行突变。