Suppose I have a class Foo
that stores two dependent attributes (both NumPy arrays) x
and y
. They should always have the same shape and satisfy x=1/y
. On possible implementation of Foo
is as follows:
class Foo:
def __init__(self, x):
self._x = np.asanyarray(x)
self._y = 1 / self.x
@property
def x(self):
ret = self._x[:]
ret.flags.writeable = False
return ret
@x.setter
def x(self, val):
val = np.asanyarray(val)
self._x = val
self._y = 1 / self.x
@property
def y(self):
ret = self._y[:]
ret.flags.writeable = False
return ret
@y.setter
def y(self, val):
val = np.asanyarray(val)
self._y = val
self._x = 1 / self.y
This guarantees that (unless the client attempts protected access), x
and y
always have the same shape and satisfy x = 1/y
. In particular, the fact that Foo.x
(similarly Foo.y
) return a read-only view of the arrays, means the client cannot modify a single element of x
(or y
), nor can (s)he performs compound assignment operators such as foo.x += 1.5
.
My question is if there is a (better) mechanism of informing Foo
of modifications in x
(or y
) so that it updates the other member variable accordingly. Specifically, I think it would be convenient from a client's perspective to be able to modify elements of x
(or y
) instead of re-assigning the entire array.
UPDATE: What is interesting is that if the attributes x
(and y
) are Python float
scalars, foo.x += 1.5
automatically calls the getter, and then the setter. (Hence the relationship between x
and y
is preserved, through the setter.) NumPy arrays (or maybe any other object that overrides __iadd__
) seem to be special.
question from:
https://stackoverflow.com/questions/65940538/how-to-inform-class-of-modifications-of-its-member-variables 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…