【发布时间】:2017-08-29 19:40:44
【问题描述】:
我有一个自定义类将 __add__ 和 __radd__ 实现为
import numpy
class Foo(object):
def __init__(self, val):
self.val = val
def __add__(self, other):
print('__add__')
print('type self = %s' % type(self))
print('type other = %s' % type(other))
return self.val + other
def __radd__(self, other):
print('__radd__')
print('type self = %s' % type(self))
print('type other = %s' % type(other))
return other + self.val
我首先测试__add__
r1 = Foo(numpy.arange(3)) + numpy.arange(3,6)
print('type results = %s' % type(r1))
print('result = {}'.format(r1))
它会导致预期的结果
>>> __add__
>>> type self = <class '__main__.Foo'>
>>> type other = <type 'numpy.ndarray'>
>>> type results = <type 'numpy.ndarray'>
>>> result = [3 5 7]
但是,测试 __radd__
r2 = numpy.arange(3) + Foo(numpy.arange(3,6))
print('type results = %s' % type(r2))
print('result = {}'.format(r2))
我明白了
>>> __radd__
>>> type self = <class '__main__.Foo'>
>>> type other = <type 'int'>
>>> __radd__
>>> type self = <class '__main__.Foo'>
>>> type other = <type 'int'>
>>> __radd__
>>> type self = <class '__main__.Foo'>
>>> type other = <type 'int'>
>>> type results = <type 'numpy.ndarray'>
>>> result = [array([3, 4, 5]) array([4, 5, 6]) array([5, 6, 7])]
这对我来说没有任何意义。 NumPy 是否为任意对象重载 __add__,然后优先于我的 __radd__?如果是,他们为什么要这样做?此外,我该如何避免这种情况,我真的希望能够在左侧添加带有 NumPy 数组的自定义类。谢谢。
【问题讨论】:
-
是的,让算术运算符与
numpy数组一起工作有点棘手,有很多底层机制。我相信numpy提供了可以让你相对轻松地做到这一点的mixin。如果没有其他人有时间,我也许可以稍后再研究。你可以read more about it here -
感谢您的链接。我没有完全理解这些 ufunc 是什么以及它们是如何工作的,但是通过在我的课堂上设置
__numpy_ufunc__ = None(__array_ufunc__ = None用于 NumPy 13.0+),我得到了我想要的结果。 -
ufuncs是向量化函数。 -
另外,您应该发布您的答案并接受它。这是一个相当不错的问题。
标签: python numpy operator-overloading