我有一个简单的向量类,它覆盖了几个算术运算符:
class vec2:
x = 0.0
y = 0.0
def __add__(self,other):
self.x = other.x
self.y = other.y
def __mul__(self,scalar):
self.x *= scalar
self.y *= scalar
然而,在其他地方我称之为这样的方法:
class foo:
position = vec2()
velocity = vec2()
def update(self,dt):
self.position += self.velocity * dt;
但是,一旦我进入更新功能,解释器就会出错:
'tuple' object has no attribute 'x'
在__add__
函数内。
为什么__add__
中的“other”作为元组而不是vec2传递?
整个代码为here。
答案 0 :(得分:1)
使用__add__
和__mul__
时返回新的向量,并处理'奇怪'类型:
class vec2:
x = 0.0
y = 0.0
def __init__(self, x=0.0, y=0.0):
self.x, self.y = x, y
def __add__(self, other):
if not isinstance(other, self.__class__):
return NotImplemented
result = self.__class__(self.x, self.y)
result.x += other.x
result.y += other.y
return result
def __iadd__(self, other):
if not isinstance(other, self.__class__):
return NotImplemented
self.x += other.x
self.y += other.y
return self
def __mul__(self, other):
if not isinstance(other, self.__class__):
return NotImplemented
result = self.__class__(self.x, self.y)
result.x *= other.x
result.y *= other.y
return result
def __imul__(self, other):
if not isinstance(other, self.__class__):
return NotImplemented
self.x *= other.x
self.y *= other.y
return self
要就地修改向量,请使用__iadd__
和__imul__
;这些仍然需要返回新值;这可以是self
。
请注意,这只是传入(x, y)
坐标的元组而不是句柄。如果要支持该用例,则需要专门处理它:
class foo:
def __init__(self, position=(0.0, 0.0), velocity=(1.0, 1.0)):
self.position = vec2()
self.velocity = vec2(*velocity)
def update(self, dt):
if isinstance(dt, tuple):
dt = vec2(*dt)
self.position += self.velocity * dt;
另请注意,您不应该为位置和力度值使用类属性;我在上面使用了实例属性,并借此机会将位置和速度设置为合理的值。
演示:
>>> f = foo()
>>> f.position.x, f.position.y
(0.0, 0.0)
>>> f.update((1, 2))
>>> f.position.x, f.position.y
(1.0, 2.0)