我编写了以下有效的代码。
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。
答案 0 :(得分: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中自己创建的更通用和高效的数值数组实现。
答案 1 :(得分:0)
重要的是要知道每http://docs.python.org/reference/datamodel.html#new-style-special-lookup(Python 3的http://docs.python.org/dev/reference/datamodel.html#special-method-lookup):
对于自定义类,只有在对象的类型上定义,而不是在对象的实例字典中,才能保证特殊方法的隐式调用正常工作。 ... 隐式特殊方法查找通常也会绕过
__getattribute__()
方法甚至是对象的元类。
因此,通过特殊方法名称实现运算符重载的唯一方法是在类上定义它们(内联或以编程方式创建类)。
有关更多详细信息和示例,请参阅http://code.activestate.com/recipes/577812-see-how-__getattribute__-interacts-with-special-me/。有关相关问题,另请参阅Overriding special methods on an instance。