Jer*_* Ma 5 python overriding numpy class operator-keyword
我试图让以下内容起作用,但没有成功:
我定义了自己的类型Unit(从内置类型继承float)来实现具有单位的数量的代数.它做的事情是这样的:
class Unit(float):
"""provide a simple unit converter for a given quantity"""
def __new__(cls, unit, num=1.):
return super(Unit, cls).__new__(cls, num)
def __init__(self, unit, num=1.):
"""set up base unit"""
self.unit = unit
def __str__(self,):
return '{:s} {:s}'.format(super(Unit, self).__str__(), self.unit)
def __rmul__(self, other):
print 'rmul: {:f}'.format(super(Unit, self).__rmul__(other))
return Unit(self.unit, super(Unit, self).__rmul__(other))
def to(self,target):
fun_conv = _conv(self.unit, target)
return Unit(target, num=fun_conv(self))
c = 3e8 * Unit('m/s') # this will 1) create a Unit instance with magnitude '1' and unit 'm/s',
# 2) invoke __rmul__ to return a new instance with number 3e8 and unit 'm/s' to variable 'c'
print c.to('km/s') # returns 3e5 km/s
Run Code Online (Sandbox Code Playgroud)
但是,__rmul__仅在float作为左操作数时才会调用此方法.如果我做这样的事情:
velocities = np.array([20, 10]) * Unit('m/s')
Run Code Online (Sandbox Code Playgroud)
然后Unit.__rmul__将不会被调用,并且numpy ndarray返回相同的内容,因为现在它Unit('m/s')被视为float值为1.0 的普通
我期望的是:之后ndarray * Unit,类似的函数Unit.to可以作为方法和属性被吸引到ndarray的实例unit,所以我可以进一步调用ndarray.to返回一个副本(或修改版本,如果它可以,为了内存效率)与新值和单位相关的原始ndarray.我该怎么办?
根据我所知道和搜索的,__mul__左操作数将是先前的*,即解释器LO.__mul__()首先检查,如果失败,则转到RO.__rmul__().我不太想要覆盖,numpy.ndarray.__mul__因为我真的不知道它会有多复杂,以及是否会有一个很大的混乱,如果它打破了ndarray对其他对象的规则.
而且,事实上我甚至都找不到在哪里定义代码__mul__的ndarray.我只是使用inspect.getsource(np.ndarray)但没有成功.为什么会失败呢?例外几乎没有IOError.
非常感谢您的关注!
如果您不继承 float,而是创建一个新类型包装 float(因此 float._ mul _(yourtype) 不起作用),则 rmul 将执行您想要的操作。不过,包装当然不是免费的......并且您必须实现您希望该类型支持的所有操作。
class T(object):
def __init__(self, val):
self.val = val
def __mul__(self, x):
print("mul")
return T(self.val*x)
def __rmul__(self, x):
print("rmul")
return T(self.val*x)
def __repr__(self):
return str(self.val)
>>> t = T(2)
>>> t * 2
mul
4
>>> 2*t
rmul
4
Run Code Online (Sandbox Code Playgroud)