ライブラリ(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]]