I have a class with an attribute ax_mask
. The attribute is list like. When I change the whole attribute or just an element of it, I need some other attribute (window
) in the class to be updated (i.e. a function update()
should be called that takes care of the update logic).
I have tried to implement the attribute as a descriptor like object. Here is my code:
import numpy as np
class AxMask:
def __set_name__(self, owner, name):
self.public_name = name
self.private_name = '_' + name
def __get__(self, obj, objtype=None):
value = getattr(obj, self.private_name)
return value
def __set__(self, obj, value):
setattr(obj, self.private_name, value)
obj.update()
def __setitem__(self, item, value):
# change item in ax_mask to value
# call Window.update()
pass
class Window:
ax_mask = AxMask() # init descriptor like object
def __init__(self, arr):
self.arr = np.asarray(arr)
self.window = self.arr # init window
shape = self.arr.shape
self.ax_mask = [np.ones((d,), dtype=bool) for d in shape] # init mask for each axis of arr with all True
def update(self):
# update window to only the rows/cols which are unmasked
ix_ = np.ix_(*self.ax_mask)
self.window = self.arr[ix_]
if __name__ == '__main__':
m, n = (10, 5)
test_arr = np.arange(m)[:, np.newaxis] + np.zeros((m, n), dtype=int)
>>> test_arr
array([[0, 0, 0, 0, 0],
[1, 1, 1, 1, 1],
[2, 2, 2, 2, 2],
[3, 3, 3, 3, 3],
[4, 4, 4, 4, 4],
[5, 5, 5, 5, 5],
[6, 6, 6, 6, 6],
[7, 7, 7, 7, 7],
[8, 8, 8, 8, 8],
[9, 9, 9, 9, 9]])
w = Window(test_arr)
row_mask = np.ones((m,), dtype=bool)
row_mask[5::] = False
>>> row_mask
array([True, True, True, True, True, False, False, False, False,
False])
w.ax_mask[0] = row_mask
>>> w.window
array([[0, 0, 0, 0, 0],
[1, 1, 1, 1, 1],
[2, 2, 2, 2, 2],
[3, 3, 3, 3, 3],
[4, 4, 4, 4, 4],
[5, 5, 5, 5, 5],
[6, 6, 6, 6, 6],
[7, 7, 7, 7, 7],
[8, 8, 8, 8, 8],
[9, 9, 9, 9, 9]])
However I want w.window
to look like this:
>>> w.window
array([[0, 0, 0, 0, 0],
[1, 1, 1, 1, 1],
[2, 2, 2, 2, 2],
[3, 3, 3, 3, 3],
[4, 4, 4, 4, 4]])
Any ideas are welcome!
Thanks to the comments I came up with a solution. I hope this will help someone. Here is the code, I replaced class
AxMask
byObservableList
:Any suggestions are welcome!