d3pd
d3pd

Reputation: 8315

How should a class that inherits from NumPy ndarray and has a default value be created?

I want to make a class that inherits from NumPy ndarray and I want to do this in such a way that I am not required to provide a value for the array on instantiation, but can have it default to something. I am having a bit of difficulty getting it working:

import numpy

class Variable(numpy.ndarray):

    def __init__(
        self,
        name                    = "trk_pt",
        tree                    = None, # tree object
        eventNumber             = None,
        eventWeight             = None,
        numberOfBins            = None, # binning
        binningLogicSystem      = None, # binning
        ):
        # arguments
        self._name              = name
        self.tree               = tree
        self.eventNumber        = eventNumber
        self.eventWeight        = eventWeight
        self.numberOfBins       = numberOfBins
        self.binningLogicSystem = binningLogicSystem
        # internal
        self.variableObject     = None
        self.variableType       = None
        self.dataType           = None
        self.variableDataTypes  = None
        self.canvas             = None
        self.histogram          = None
        self._values            = [] # list of values
        self._valuesRaw         = [] # list of unmodified, raw values
        # NumPy ndarray inheritance
        #self = ([1])
        if sys.version_info >= (3, 0):
            super().__init__([1])
        else:
            super(numpy.ndarray, self).__init__([1])

a = Variable()

The error I am presented with is as follows:

TypeError: Required argument 'shape' (pos 1) not found

How do I code this such that the array has a default value on instantiation and does not require a value?

Upvotes: 4

Views: 3003

Answers (1)

unutbu
unutbu

Reputation: 880577

Using this example from the docs as a guide, you could use

    self = np.asarray([1]).view(cls)

to instantiate the array in __new__:

import numpy as np

class Variable(np.ndarray):

    def __new__(
        cls,
        name                    = "trk_pt",
        tree                    = None, # tree object
        eventNumber             = None,
        eventWeight             = None,
        numberOfBins            = None, # binning
        binningLogicSystem      = None, # binning
        ):
        self = np.asarray([1]).view(cls)
        self._name              = name
        self.tree               = tree
        self.eventNumber        = eventNumber
        self.eventWeight        = eventWeight
        self.numberOfBins       = numberOfBins
        self.binningLogicSystem = binningLogicSystem
        ...
        return self

a = Variable()

Note also that help(np.ndarray) says

No __init__ method is needed because the array is fully initialized after the __new__ method.

Upvotes: 4

Related Questions