【发布时间】:2012-10-12 21:06:26
【问题描述】:
我有一个来自库 (numpy.ndarray) 的对象,其中我已将 _iadd_ 方法替换为自定义方法。 如果我调用 object._iadd_(x),它会按预期工作。但是, object+=x 似乎调用了旧的(未替代的)方法。 我想防止 numpy 在特定情况下发生溢出,所以我为此创建了一个上下文管理器。这是(仍然很粗略的)代码:
class NumpyOverflowPreventer( object ):
inverse_operator= {'__iadd__':'__sub__', '__isub__':'__add__', '__imul__': '__div__', '__idiv__':'__mul__'}
def _operate(self, b, forward_operator):
assert type(b) in (int, float)
reverse_operator= NumpyOverflowPreventer.inverse_operator[forward_operator]
uro= getattr(self.upper_range, reverse_operator)
lro= getattr(self.lower_range, reverse_operator)
afo= self.originals[ forward_operator ]
overflows= self.matrix > uro( b )
underflows= self.matrix < lro( b )
afo( b )
self.matrix[overflows]= self.upper_range
self.matrix[underflows]= self.lower_range
def __init__(self, matrix):
m= matrix
assert m.dtype==np.uint8
self.matrix= m
self.lower_range= float(0)
self.upper_range= float(2**8-1)
def __enter__(self):
import functools
self.originals={}
for op in NumpyOverflowPreventer.inverse_operator.keys():
self.originals[ op ] = getattr( self.matrix, op )
setattr( self.matrix, op, functools.partial(self._operate, forward_operator=op))
def __exit__(self, type, value, tb):
for op in NumpyOverflowPreventer.inverse_operator.keys():
setattr( self.matrix, op, self.originals[ op ] )
运行这个:
a= np.matrix(255, dtype= np.uint8)
b= np.matrix(255, dtype= np.uint8)
with NumpyOverflowPreventer(a):
a+=1
with NumpyOverflowPreventer(b):
b.__iadd__(1)
print a,b
返回这个:
[[0]] [[255]]
【问题讨论】:
-
看起来您正在实例上设置就地运算符方法。那是行不通的; Python 不会在实例上查找特殊方法,只会在类上查找。
-
@kindall 为什么不将其发布为答案? (只是好奇)
-
@VasiliyFaronov:因为我没有花时间真正深入理解代码或提出解决方案。
-
@kindall 确实,因此失败了,感谢您的澄清
标签: python numpy operator-keyword