【问题标题】:How do I implement polymorphic arithmetic operators pythonicly?如何以 Python 方式实现多态算术运算符?
【发布时间】:2010-03-02 23:36:12
【问题描述】:

我正在尝试创建一个类,该类允许我将同一类的对象添加/相乘/除法或将数字参数添加/相乘到类的每个成员

所以我的课程是针对坐标的(我知道有很多很棒的软件包可以比我自己希望做的更好,但现在我只是好奇)。

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 块中折腾我只是好奇我应该如何解决这个问题。

【问题讨论】:

    标签: python polymorphism type-conversion


    【解决方案1】:

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

    【讨论】:

    • 请求宽恕是解决错误同源问题的好方法,但在重载数字运算符的情况下,x、y 和 z 的含义非常清楚。如果你添加一个完全不相关的四维 (w,x,y,z) 数字类的实例,你只会遇到问题:然后你会默默地失去 w。
    • 太棒了,谢谢。这就是我最终要做的(和__radd__ = __add__)。我感觉有点老套,但它很适合我的目的,而且似乎很受欢迎。
    • 如果你的 except 块返回了self + GpsPoint(other, other, other) 这似乎更像是你将数字映射到 GpsPoints 的想法,你想将它们更改为 GpsPoints,然后添加它们。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      简答:使用 isinstance()。

      没有其他方法可以在您的方法中确定“其他”的类型。此外,如果您查看许多 python 库的源代码,您会发现有很多地方使用了 isinstance()。所以这只是python中的最新技术:-)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-11-11
        • 2011-02-28
        • 1970-01-01
        • 1970-01-01
        • 2022-01-07
        • 2021-11-03
        • 1970-01-01
        • 2020-03-31
        相关资源
        最近更新 更多