3

動作する次のコードを作成しました。

from operator import mul
from operator import truediv #python 3.2

class Vec(list):

    def __mul__(self, other):
        return Vec(map(mul, self, other))

    def __truediv__(self, other):
        return Vec(map(truediv, self, other))


>>> xs = Vec([1,2,3,4,5])
>>> ys = Vec([4,5,6,7,4])
>>> zs = xs * ys
>>> zs.__class__
<class 'vector.Vec'>
>>> zs
[4, 10, 18, 28, 20]

しかし、次のようなものを作成することは可能ですか:

class Vec(list):

    allowed_math = [__add__, __mul__, __truediv__, __subtract__] # etc

    def __catchfunction__(self, other, function):
        if function in allowed_math:
            return Vec(map(function, self, other))

明確にするために、これは私がNumPyを再作成しようとしているということではなく、単にPythonで遊ぶ方法を理解しようとしているだけです。

4

2 に答える 2

3

目的の効果を達成するための1つのオプションは次のとおりです。

class Vec(list):
    pass

functions = {"__add__": operator.add,
             "__mul__": operator.mul,
             "__truediv__": operator.truediv,
             "__sub__": operator.sub}
for name, op in functions.iteritems():
    setattr(Vec, name, lambda self, other, op=op: Vec(map(op, self, other)))

op=opラムダ関数がのクロージャーになるのを避けるために、パラメーターが必要であることに注意してくださいop

ただし、NumPyを使用する方がはるかに優れている場合があります。これは、純粋なPythonで自分で作成するよりも、はるかに用途が広く効率的な数値配列の実装を提供します。

于 2012-06-26T13:40:49.457 に答える
0

知っておくべき重要なことは、http://docs.python.org/reference/datamodel.html#new-style-special-lookup ( http://docs.python.org/dev/reference/datamodel.html# Python 3の特別なメソッド ルックアップ):

カスタム クラスの場合、特別なメソッドの暗黙的な呼び出しは、オブジェクトのインスタンス ディクショナリではなく、オブジェクトの型で定義されている場合にのみ正しく動作することが保証されます。... 暗黙の特別なメソッド検索は、通常__getattribute__()、オブジェクトのメタクラスのメソッドもバイパスします。

したがって、特別なメソッド名を使用して演算子のオーバーロードを実装する唯一の方法は、クラスでそれらを定義することです (インラインまたはプログラムによるクラス作成後に)。

詳細と例については、http://code.activestate.com/recipes/577812-see-how-__getattribute__-interacts-with-special-me/を参照してください。関連する質問については、インスタンスでの特別なメソッドのオーバーライドも参照してください。

于 2012-06-26T14:03:14.320 に答える