Suppose I have a simple Test
class which inherits from numpy.ndarray
(documentation on ndarray
subclassing). This class creates an object which is a partial view of another ndarray
. Now I would like to create a method that modifies this view in-place. Something like:
import numpy
class Test(numpy.ndarray):
def __new__(cls, info='Test class'):
base = numpy.ndarray.__new__(cls, (6, 2), dtype=float)
view = base[0:2, :]
view.info = info
return view
def __array_finalize__(self, obj):
if obj is None:
return
self.info = getattr(obj, 'info', None)
def change_view(self, start, stop):
"""This is the method I'd like to implement"""
# Incorrect, but represents what I am looking for
self = self.base[start:stop]
if __name__ == '__main__':
t = Test()
print(t)
print(t.info)
t.change_view(1, 5)
print(t)
print(t.info)
I would expect the method .change_view(x)
to modify the view of the .base
attribute to show rows [1:5]
instead of [0:2]
, which is the default in __new__()
.
Is this possible? If so, how? Otherwise, why not? Note that .base
never changes (it always occupies the same memory space), I just want to change the view of it.
Notes
- See the comments in
change_view()
. I knowself = self.base[start:stop]
is not correct, and I know and understand why, but I think it is a short way to represent what I am looking for. - As noted in the answers bellow, one could think of
self[:] = ...
orself.data = ...
. However, this will not work when changing the view size (which is exactly the case).
References
This question was already asked here (or at least it is a similar case), but answers referred to solutions which returned the modified array (i.e. no in-place modification) or which used a wrapper object (i.e. having an attribute with the array that is to be modified).
I am aware of those possibilities, and I know they can be simpler or even more convenient. However, I would like to understand why (if so) it is not possible to do what I am looking for.