如何pythonicly实现多态算术运算符?

时间:2010-03-02 23:36:13

标签: python polymorphism type-conversion

我正在尝试创建一个类,允许我将同一个类的对象添加/相乘/分割,或者为该类的每个成员添加/乘以数字参数

所以我的班级是坐标(我知道有很棒的套餐可以做我想要的一切比我自己想要的更好,但现在我只是好奇)。

class GpsPoint(object):
    """A class for representing gps coordinates"""
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z
    def __add__(self, other):
        return GpsPoint(self.x + other.x, self.y + other.y, self.z + other.z)
    def __radd__(self, other):
        return GpsPoint(self.x + other, self.y + other, self.z + other)
    def __str__(self):
        return "%d, %d, %d" % (self.x, self.y, self.z)

这是我最初的尝试。我发现它有效,但只有我先使用数字参数

>>foo = GpsPoint(1,2,3)
>>print 5 + foo
6, 7, 8
>>print foo + 5
AttributeError: 'int' object has no attribute 'x'

那么,做到这一点的pythonic方法是什么,有一种pythonic方式,这只是愚蠢吗?我看到使用isinstance()时出现的哲学问题是什么,我知道我可以在try except块中抛弃我只是好奇我应该如何

3 个答案:

答案 0 :(得分:6)

“Pythonic”方式是“请求宽恕而不是许可” - 也就是说,不是事先检查类型,而是尝试添加,如果失败,则捕获异常并处理它,如下所示:

class GpsPoint(object):
    """A class for representing gps coordinates"""
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z
    def __add__(self, other):
        try:
            return GpsPoint(self.x + other.x, self.y + other.y, self.z + other.z)
        except AttributeError:
            return GpsPoint(self.x + other, self.y + other, self.z + other)
    def __radd__(self, other):
        try:
            return GpsPoint(self.x + other.x, self.y + other.y, self.z + other.z)
        except AttributeError:
            return GpsPoint(self.x + other, self.y + other, self.z + other)
    def __str__(self):
        return "%d, %d, %d" % (self.x, self.y, self.z)

答案 1 :(得分:2)

您将不得不尝试确定other的类型,至少在与GpsPoint兼容的范围内。如果你无法弄明白,那么只需返回NotImplemented,解释器就会尝试从那里处理它。

答案 2 :(得分:0)

简短回答:使用isinstance()。

没有其他方法可以破坏方法中“其他”的类型。此外,如果您检查许多python库的源代码,您会发现有很多地方使用了isinstance()。所以这只是python中的艺术状态:-)。