[英]How do I write a class that behaves like a numpy.ndarray without subclassing numpy.ndarray?
Let's assume the following given class definition: 让我们假设以下给定的类定义:
class Numeric(object):
def __init__(self, signal):
self.signal = signal
Now, with the requirement that Numeric
doesn't inherit from numpy.ndarray
, how do I have to extend that definition that Numeric
behaves like a numpy.ndarray
? 现在,由于要求Numeric
不能从numpy.ndarray
继承,我该如何扩展Numeric
行为类似于numpy.ndarray
定义?
edit: signal
should be a np.ndarray
(or similar, like quantities.Quantity
). 编辑: signal
应该是一个np.ndarray
(或类似的,如quantities.Quantity
。 quantities.Quantity
)。 I have the following scenarious in mind: 我想到以下方案:
import numpy as np
import quantities as pq
a = Numeric(pq.Quantity([1,2,3], 'mV'))
b = Numeric(pq.Quantity([1,3,5], 's'))
c = Numeric(np.array([10,20,30]))
a = Numeric(np.array([1,2,3]))
b = Numeric(np.array([1,3,5]))
a * c
a * b
a * np.array([3,4,5])
and: 和:
import matplotlib.pyplot as plt
plt.plot(b)
With a decorator for adapting numpy
-functions and an implementation of __array__
within Numeric
I can solve most problems: 使用修饰器来适应numpy
函数,并在Numeric
实现__array__
,我可以解决大多数问题:
def adapt_signal_functions(cls):
def generateAdjustedFunction(functionName):
print functionName
def foo(self, *args, **kwargs):
function = getattr(self.signal.__class__, functionName)
return function(self.signal, *args, **kwargs)
return foo
functionNames = [
'_get_units',
'_set_units',
'rescale',
'ptp',
'clip',
'copy',
'compress',
'conj',
'cumprod',
'cumsum',
'diagonal',
'dot',
'flatten',
'getfield',
'round',
'trace',
'max',
'mean',
'min',
'newbyteorder',
'prod',
'ravel',
'reshape',
'resize',
'round',
'std',
'sum',
'trace',
'transpose',
'var',
'__getitem__',
'__getslice__',
'__abs__',
#
'__add__',
'__div__',
'__divmod__',
'__floordiv__'
'__mod__',
'__mul__',
'__pow__',
'__sub__',
#
'__radd__',
'__div__',
'__divmod__',
'__rfloordiv__',
'__rmod__',
'__imul__',
#'__rmul__',
'__rpow__',
'__rsub__',
]
for functionName in functionNames:
foo = generateAdjustedFunction(functionName)
setattr(cls, functionName, foo)
return cls
@adapt_signal_functions
class Numeric(object):
def __init__(self, signal):
self.signal = signal
self.adapt_quantity()
def adapt_quantity(self):
if hasattr(self.signal, '_dimensionality'):
self._dimensionality = self.signal._dimensionality
self.dimensionality = self.signal.dimensionality
def __array__(self):
return self.signal
With that I can do: 这样我可以做到:
import numpy as np
import quantities as pq
a = Numeric(pq.Quantity([1,2,3], 'mV'))
b = Numeric(pq.Quantity([1,3,5], 's'))
c = Numeric(np.array([10,20,30]))
n = np.array([1,2,3])
a * a
a * c
a * n
a.max()
print type(a * n) == type(a.signal * n)
# >>> True
print type(a * c) == type(a.signal * c.signal)
# >>> True
Return types correspond to the equivalent return type of Numeric.signal
. 返回类型对应于Numeric.signal
的等效返回类型。
One problem remains: 仍然存在一个问题:
print type(n * a) == type(n * a.signal)
# >>> False
Any ideas, how to fix that? 有什么想法,如何解决?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.