簡體   English   中英

如何編寫一個行為類似於numpy.ndarray的類而又不繼承numpy.ndarray的類?

[英]How do I write a class that behaves like a numpy.ndarray without subclassing numpy.ndarray?

讓我們假設以下給定的類定義:

class Numeric(object):
  def __init__(self, signal):
    self.signal = signal

現在,由於要求Numeric不能從numpy.ndarray繼承,我該如何擴展Numeric行為類似於numpy.ndarray定義?

編輯: signal應該是一個np.ndarray (或類似的,如quantities.Quantityquantities.Quantity )。 我想到以下方案:

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])

和:

import matplotlib.pyplot as plt
plt.plot(b)

使用修飾器來適應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

這樣我可以做到:

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

返回類型對應於Numeric.signal的等效返回類型。

仍然存在一個問題:

print type(n * a) == type(n * a.signal)
# >>> False

有什么想法,如何解決?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM