我有一个图书馆的东西(numpy.ndarray公司),其中我用uu iadd\uuu方法替换了一个自定义方法。 如果我调用object.\u iadd\uux,它将按预期工作。但是,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]]
您看到的问题是没有在实例上查找特殊的内置方法。它们是在
matrix
类型上查找的。因此,在实例上替换它们不会导致它们被间接使用。你知道吗实现目标的一种方法是将
NumpyOverflowPreventer
作为要处理的操作的包装器。。。你知道吗我只在这里定义了
__iadd__
,我确信您可以通过一些元类/装饰器操作动态地完成所有这些操作……但我保持简单。你知道吗用法:
如果有人对溢出问题感兴趣,并且相信jdi和kindall的专业知识,那么操作符似乎必须是类方法——因此,动态方法生成需要一个自定义类我已经到达了以下工作原型(对于+=,-=,*=)。/=)
相关问题 更多 >
编程相关推荐