-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__とを使用して新しいベクトルを返し__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 に答える