python 阻止接线员呼叫
python prevent operator call
我有一个 class CustomArray
类似于 numpy.ndarray
。它重载了一堆算术运算符,如 __add__
、__mul__
等。由于人们很可能将它与 numpy 结合使用,我担心有时会调用 numpy.ndarray
运算符而不是 CustomArray
。最糟糕的是它们实际上起作用并产生了一些不需要的结果。
a = np.array([1, 2, 3])
b = CustomArray([1, 2, 3])
c = a + b # np.ndarray.__add__ will be called!
有什么办法可以防止这种情况发生吗?所以解释器要么引发错误,要么总是喜欢 CustomArray
运算符重载。
在 NumPy 1.13 中,有新的 __array_ufunc__
API。此 API 是 临时的 ,尚不能保证向后兼容性。
numpy.ndarray
将其运算符委托给 NumPy ufuncs,如果找到它,NumPy ufuncs 将委托给 __array_ufunc__
以实现 ufunc 行为。此跳过的规则 numpy.ndarray.__array_ufunc__
,因此如果您实现自己的 __array_ufunc__
,在将您的实例与 NumPy 数组一起使用时,它将始终优先。
如果您想禁用对象上的所有 ufunc,可以在 class 上设置 __array_ufunc__ = None
:
class CustomArray(...):
__array_ufunc__ = None
或者,如果你想实现它,签名是
def __array_ufunc__(self, ufunc, method, *inputs, **kwargs)
您感兴趣的案例,
ufunc
是ufunc对象(例如,numpy.add
代表+
),
method
是 "__call__"
,
inputs
是元组 (left operand, right operand)
,
kwargs
为空。
对于更高级的案例,method
、inputs
和 kwargs
可能有所不同,因此如果您不想处理这些案例,请 return NotImplemented
。
举个例子,如果你想用 NumPy 数组重载 +
,你可以写
def __array_ufunc__(self, ufunc, method, *inputs, **kwargs):
if ufunc is not numpy.add:
return NotImplemented
if method != "__call__":
return NotImplemented
if kwargs:
return NotImplemented
return my_addition_logic(*inputs)
您还需要实施 __add__
。
我有一个 class CustomArray
类似于 numpy.ndarray
。它重载了一堆算术运算符,如 __add__
、__mul__
等。由于人们很可能将它与 numpy 结合使用,我担心有时会调用 numpy.ndarray
运算符而不是 CustomArray
。最糟糕的是它们实际上起作用并产生了一些不需要的结果。
a = np.array([1, 2, 3])
b = CustomArray([1, 2, 3])
c = a + b # np.ndarray.__add__ will be called!
有什么办法可以防止这种情况发生吗?所以解释器要么引发错误,要么总是喜欢 CustomArray
运算符重载。
在 NumPy 1.13 中,有新的 __array_ufunc__
API。此 API 是 临时的 ,尚不能保证向后兼容性。
numpy.ndarray
将其运算符委托给 NumPy ufuncs,如果找到它,NumPy ufuncs 将委托给 __array_ufunc__
以实现 ufunc 行为。此跳过的规则 numpy.ndarray.__array_ufunc__
,因此如果您实现自己的 __array_ufunc__
,在将您的实例与 NumPy 数组一起使用时,它将始终优先。
如果您想禁用对象上的所有 ufunc,可以在 class 上设置 __array_ufunc__ = None
:
class CustomArray(...):
__array_ufunc__ = None
或者,如果你想实现它,签名是
def __array_ufunc__(self, ufunc, method, *inputs, **kwargs)
您感兴趣的案例,
ufunc
是ufunc对象(例如,numpy.add
代表+
),method
是"__call__"
,inputs
是元组(left operand, right operand)
,kwargs
为空。
对于更高级的案例,method
、inputs
和 kwargs
可能有所不同,因此如果您不想处理这些案例,请 return NotImplemented
。
举个例子,如果你想用 NumPy 数组重载 +
,你可以写
def __array_ufunc__(self, ufunc, method, *inputs, **kwargs):
if ufunc is not numpy.add:
return NotImplemented
if method != "__call__":
return NotImplemented
if kwargs:
return NotImplemented
return my_addition_logic(*inputs)
您还需要实施 __add__
。