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

达到预期效果的一种选择是:

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参数是必要的,以避免 lambda 函数成为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 回答