Python运算符重载不起作用



我有一个Vector2类:

class Vector2():
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def __add__(self, other):
return Vector2(self.x + other.x, self.y + other.y)
def __sub__(self, other):
return Vector2(self.x - other.x, self.y - other.y)
def __mul__(self, other):
return Vector2(self.x * other, self.y * other)
def __neg__(self):
return Vector2(-self.x, -self.y)
def magnitude(self):
return math.sqrt(self.x ** 2 + self.y ** 2)
@classmethod
def distance(self, v1, v2):
return math.sqrt((v2.x - v1.x) ** 2 + (v2.y - v1.y) ** 2)
def normalize(self):
return self * (1/self.magnitude())

当我尝试执行1.0 * Vector2()时,我会得到错误:TypeError:*的操作数类型不受支持:"float"one_answers"instance">

然而,有时它会按预期工作:

#this works as intended, s is a float
ball.pos -= ball.vel.normalize() * s

ball.vel是一个向量,我可以乘以一个浮点值。在我的代码的许多部分中,矢量与浮点相乘,没有错误。

有人知道这种不一致是从哪里来的吗?

感谢

定义一个__rmul__方法以使a_float * a_vector工作。它可以像一样简单

def __rmul__(self, other):
return self * other

其他操作符也有一个dunder-r版本。当没有为给定类型定义正常版本时,会调用这些反射运算符。请参阅有关NotImplemented内置常量的文档。

表达式a * b等效于a.__mul__(b),除非ba类的子类的实例,或者a.__mul__(b)返回NotImplemented,在这种情况下它是b.__rmul__(a)

这是为其他偶然发现这个问题的人准备的。我正在学习运算符重载(学习SQLalchemy如何通过添加两列来返回BinaryExpression(。不管怎样,我的简单代码看起来应该有效。我在一个蟒蛇游乐场里运行它(我不会指名道姓(,它一直失败/甚至不会运行。它给了我一条错误消息'Suspension error, cannot call a function that blocks or suspends here on line X in main.py'.

5分钟后,我尝试了另一个操场,结果似乎也遇到了同样的问题。它开始运行时没有任何错误,但什么也没做,只是超时了,所以我认为这也是一样的——也就是我的代码。

我花了20分钟阅读S/O,并尝试调试和尝试不同的组合。操作员过载甚至没有被呼叫(当我运行print('add called')时。我准备拔头发,但我尝试了第三个操场,在我认为会的所有组合中,一切都如预期的那样达到了T。

我把同样的代码复制到了其他操场上,但它们仍然以同样的方式失败,所以这根本不是代码。顺便说一句,它也在本地脚本中工作。

我不知道这些游乐场运行的是什么版本的Python,但我想它至少是Python3。为了给你更多的信息,我尝试了print(sys.version)(当然是在导入sys之后(,即使在两个失败的操场上也失败了,但在一个成功的操场上成功了。我不知道他们的问题是什么,但事情就是这样。

最重要的是,你(显然(不能相信这些蟒蛇游乐场能正常工作,即使它们在你的搜索结果中排名靠前。WYSINWYG。我只是想把它放在那里,以防任何需要它的人偶然发现。这也是旅程的一部分。

最新更新