我有一个带有属性
ax_mask
的类。该属性类似于列表。当我更改整个属性或仅更改其中的一个元素时,我需要更新类中的其他属性 (window
)(即应调用函数 update()
来处理更新逻辑)。
我尝试将属性实现为类似对象的描述符。这是我的代码:
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]])
但是我希望
w.window
看起来像这样:
>>> 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]])
欢迎任何想法!
感谢评论,我想出了一个解决方案。我希望这会对某人有所帮助。这是代码,我用
AxMask
替换了 ObservableList
类:
import numpy as np
class ObservableList(list):
"""Notifies the owner when an item is set"""
def __init__(self, iterable, owner):
super().__init__(iterable)
self.owner = owner
def __setitem__(self, key, value):
super().__setitem__(key,value)
self.notify()
def notify(self):
self.owner.update()
class Window:
def __init__(self, arr):
self.arr = np.asarray(arr)
self.window = self.arr
shape = self.arr.shape
self._ax_mask = ObservableList([np.ones((d,), dtype=bool) for d in shape], self)
@property
def ax_mask(self):
return self._ax_mask
@ax_mask.setter
def ax_mask(self, iterable):
self._ax_mask = ObservableList(iterable, self)
self.update()
def update(self):
ix_ = np.ix_(*self.ax_mask) # advanced indexing -> no view, but copy;
self.window = self.arr[ix_]
有任何建议欢迎提出!