Subclassing and extending numpy.ndarray
I need some basic representations of the data class, and I want to use the existing numpy classes as they already offer great functionality.
However, I'm not sure if this is the way to do it (although it works so far). So here's an example:
The class Position
should act as simple numpy.array
, but it should display attributes .x
, .y
and .z
for the three components of the array. I have overwritten the method __new__
that returns ndarray
with the original array. To allow access and modification of the array, I defined properties along with settings for each one.
import numpy as np
class Position(np.ndarray):
"""Represents a point in a 3D space
Adds setters and getters for x, y and z to the ndarray.
"""
def __new__(cls, input_array=(np.nan, np.nan, np.nan)):
obj = np.asarray(input_array).view(cls)
return obj
@property
def x(self):
return self[0]
@x.setter
def x(self, value):
self[0] = value
@property
def y(self):
return self[1]
@y.setter
def y(self, value):
self[1] = value
@property
def z(self):
return self[2]
@z.setter
def z(self, value):
self[2] = value
It seems, however, too much code for such basic logic, and I'm wondering if I'll do it the "right" way. I also need a bunch of other classes like Direction
that that will have quite a few other features (auto-norm on change, etc.), and before I start integrating numpy I thought I was asking you ...
source to share
I would say ndarray is the wrong choice here, you probably want a simple namedtuple.
>>> import collections
>>> Position = collections.namedtuple('Positions', 'x y z')
>>> p = Position(1, 2, 3)
>>> p
Positions(x=1, y=2, z=3)
You can get unboxing this way
>>> x, y, z = p
>>> x, y, z
(1, 2, 3)
>>>
source to share