【问题标题】:__add__ operator overloading does not work as expected__add__ 运算符重载无法按预期工作
【发布时间】:2020-09-12 11:06:50
【问题描述】:

所以我最近了解了 python 中的运算符重载,并尝试在我正在处理的项目中使用它。贝娄,我试图重现我遇到的问题。

class Ship:
    def __init__(self, pos):
        self.pos = pos
        self.center = [18, 30]
        self.leftNozzlePos = [6, 10]
        self.rightNozzlePos = [30, 10]
        self.mainNozzlePos = [18, 60]

    def __add__(p1, p2):
        x = p1[0] + p2[0]
        y = p1[1] + p2[1]
        return [x, y]

    def updateRelativePositions(self):
        self.center = self.pos + self.center
        self.leftNozzlePos = self.pos + self.leftNozzlePos
        self.rightNozzlePos = self.pos + self.rightNozzlePos
        self.leftNozzlePos = self.pos + self.mainNozzlePos

ship = Ship([600, 300])
ship.updateRelativePositions()
print(ship.mainNozzlePos)

所以我有一堆位置值作为[x, y] 存储在列表中。我试图重载__add__ 运算符,使其返回[p1[0]+p2[0], p1[1]+p2[1]]p1p1 是两个不同的列表持有位置。正如您在函数updateRelativePositions 中看到的那样,我尝试添加一些位置值,结果很奇怪。对于leftNozzlePosrightNozzlePos,它会打印一个包含4 个项目的列表,而对于mainNozzlePos,它会返回完全不变的值。为什么会发生这种情况,我该如何解决?感谢您的帮助

【问题讨论】:

  • ` def __add__(p1, p2):` --> ` def __add__(self,other):`

标签: python python-3.x add


【解决方案1】:

__add__ 适用于您自己添加实例时(例如,执行ship + ship 或其他操作);你不是,你正在添加实例的随机属性(当涉及lists 时会导致连接)。

mainNozzlePos 未更改的原因是您不小心将其分配给了 leftNozzlePos(覆盖了您之前计算的两行)。

运算符重载在这里没有意义,因为您不尝试支持将一个 Ship 添加到另一个(这甚至意味着什么?)。您可以将 numpy 数组用于您的成员变量,这将在调用 + 时进行元素相加而不是串联,或者您可以使用简单的辅助方法来显式地执行您想要执行的操作,例如

class Ship:
    # __init__ omitted for brevity

    @staticmethod
    def _addpoints(p1, p2):
        x = p1[0] + p2[0]
        y = p1[1] + p2[1]
        return [x, y]

    def updateRelativePositions(self):
        self.center = self._addpoints(self.pos, self.center)
        self.leftNozzlePos = self._addpoints(self.pos, self.leftNozzlePos)
        self.rightNozzlePos = self._addpoints(self.pos, self.rightNozzlePos)
        self.mainNozzlePos = self._addpoints(self.pos, self.mainNozzlePos)

或者,您可以定义:

    def _addpos(self, pt):
        pt[0] += self.pos[0]
        pt[1] += self.pos[1]

并避免在每次调用时显式传递self.pos(代价是使函数仅将self.pos 添加到事物中,而不是任意点)并且需要在最后重新分配,从而使调用简化为:

    def updateRelativePositions(self):
        self._addpos(self.center)
        self._addpos(self.leftNozzlePos)
        self._addpos(self.rightNozzlePos)
        self._addpos(self.mainNozzlePos)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-25
    • 1970-01-01
    • 2020-11-25
    相关资源
    最近更新 更多