2011-08-20 8 views
19

私はPythonでベクトルを表現するためのクラスを作成しました(練習問題として)、組み込み演算子の拡張に問題があります。ユーザ定義の__mul__メソッドは可換ではありません

ベクタークラスのために__mul__メソッドを定義しました。問題は、式x * yでは、インタプリタが__mul__というxのメソッドであり、yではないということです。

したがってvector(1, 2, 3) * 2は、ベクトル< 2、4,6>を返します。 2 * vector(1, 2, 3)は、組み込みのintクラスがユーザー定義のベクトルによる乗算をサポートしていないため、TypeErrorを作成します。

私は単に

def multiply(a, b): 
    try: 
     return a * b 
    except TypeError: 
     return b * a 

新しい乗算機能を書き込むことによって、この問題を解決することができますが、これは私が私のユーザー定義クラスで使用するすべての関数を再定義が必要となります。

組み込み関数でこれを正しく処理する方法はありますか?

答えて

24

異なるタイプのcommutativity を使用する場合は、__rmul__()を実装する必要があります。実装されている場合は、__r*__()のような特別なメソッドが呼び出されます。そうでなければ、TypeErrorが発生します。引数が入れ替わっていることに注意してください:

class Foo(object): 
    def __mul_(self, other): 
     ''' multiply self with other, e.g. Foo() * 7 ''' 
    def __rmul__(self, other): 
     ''' multiply other with self, e.g. 7 * Foo() ''' 
+0

を探していると信じてどのようにPythonは 'Fooの.__ rmul__'はなく、他のオブジェクトの' __mul__'を呼び出すために知っているのですか? –

+2

左側の '__mul__'を使用しようとしますが、見つからない場合は右側の' __rmul__'を探します。 –

+3

@pstの場合、Pythonはまず '__mul__'を呼び出しますが、存在しないか、' NotImplemented'を返すと、Pythonは他のオブジェクトの '__rmul__'を呼び出します。 ( '__mul__'が実行を呼び出すと、' __rmul__'は__not__が呼び出されることに注意してください。 –

関連する問題