【问题标题】:is there a more efficient way of overloading operators than the way I have in python?有没有比我在 python 中更有效的重载运算符的方法?
【发布时间】:2020-05-23 08:29:02
【问题描述】:

我有一个 Python 类,它可以让你用两个 x-y 坐标点来初始化线条。我还有一个将两行加在一起的功能,如下所示:

class Line:
    def __init__(self, x1, y1, x2, y2):
        ...

    def __add__(self, other):
        new_x1 = self.x1 + other.x1
        new_y1 = self.y1 + other.y1
        new_x2 = self.x2 + other.x2
        new_y2 = self.y2 + other.y2
        return Line(new_x1, new_y1, new_x2, new_y2)

我有非常相似的减法和乘法函数,它们与 add 函数相同,但内部有不同的运算符符号。

我的问题是,有没有更好或更有效的方法来写这个?

【问题讨论】:

  • 为什么Line 类中的重载加法返回Point 对象?两个Point项相加是什么意思? (除了仿射几何,你不用加点)
  • 抱歉,打错了。它应该是线

标签: python function class operator-overloading


【解决方案1】:

稍微简洁一点:

class Line:
    def __init__(self, x1, y1, x2, y2):
       self.x1, self.y1, self.x2, self.y2 = x1, y1, x2, y2

    def operation(self, other, op):
        new_x1 = op(self.x1, other.x1)
        new_y1 = op(self.y1, other.y1)
        new_x2 = op(self.x2, other.x2)
        new_y2 = op(self.y2, other.y2)
        return Point(new_x1, new_y1, new_x2, new_y2)

    def __add__(self, other):
        return self.operation(other, float.__add__)

    def __sub__(self, other):
        return self.operation(other, float.__sub__)

【讨论】:

  • op 参数未在operation() 中使用。
  • @AKX 请再看一遍。它被使用了 4 次。
  • 不,不使用op 名称。您的意思可能是像 getattr(self.x1, op) 这样按名称访问属性。
  • 啊,是的。很抱歉造成误会。
【解决方案2】:

您可以利用相似之处。如果你还定义了__neg__,你会得到更容易的 add/sub 实现为 sub == -add

class Line:
    def __init__(self, x1, y1, x2, y2):
        self.x1, self.y1, self.x2, self.y2 = x1, y1, x2, y2

    def __add__(self, other):
        new_x1 = self.x1 + other.x1
        new_y1 = self.y1 + other.y1
        new_x2 = self.x2 + other.x2
        new_y2 = self.y2 + other.y2
        return Line(new_x1, new_y1, new_x2, new_y2)

    def __sub__(self, other):
        return self + (-other)  # leverage __neg__

    def __neg__(self):
        return Line(-self.x1,-self.y1,-self.x2,-self.y2)

    def __str__(self):
        return f"({self.x1}/{self.y1})->({self.x2}/{self.y2})"


l = Line(0,0,10,10)
l2 = Line(5,5,.20,20)

print(l) 
print(l2) 
print(l-l2)

输出:

(0/0)->(10/10)
(5/5)->(0.2/20)
(-5/-5)->(9.8/-10)

但在大多数情况下,这并没有多大意义,因为操作可能会根据您的班级所在的领域而大不相同。

【讨论】:

    【解决方案3】:

    @Blotosmeteks 答案的操作很棒。但除此之外,您也可以这样做。

    class Line:
        def __init__(self, x1, y1, x2, y2):
            self.x1, self.y1, self.x2, self.y2 = float(x1), float(y1), float(x2), float(y2)
    
        def operation(self, other, op):  # Removing the declarations on multiple lines here.
            return Point(op(self.x1, other.x1), op(self.y1, other.y1),
                    op(self.x2, other.x2), op(self.y2, other.y2))
    
        def __add__(self, other):
            return self.operation(other, float.__add__)
    
        def __sub__(self, other):
            return self.operation(other, float.__sub__)
    

    【讨论】:

    • op 参数未在operation() 中使用。
    猜你喜欢
    • 2019-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多