-2

我有一个简单的向量类,它重载了几个算术运算符:

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__作为元组传递,而不是 vec2?

完整的代码在这里

4

1 回答 1

1

使用__add__and时返回新向量__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)
于 2012-09-18T10:24:49.087 回答