param icon indicating copy to clipboard operation
param copied to clipboard

Callbacks not triggered when value updated at the class level before being set on an instance

Open maximlt opened this issue 2 years ago • 2 comments

Param allows to update the value of instances of a class from the class level, when the value hasn't yet been set (constructor or setattr), e.g.:

import param

class P(param.Parameterized):
    m = param.Parameter(0)
    n = param.Parameter(0)
    o = param.Parameter(0)

p = P(n=1)
p.o = 1
P.m = P.n = P.o = 2
print(f'{p.m=} {p.n=} {p.o=}')
# p.m=2 p.n=1 p.o=1

However, watching a parameter changed at the class level doesn't trigger its callbacks, while it certainly should:

import param

class P(param.Parameterized):
    m = param.Parameter()

    @param.depends('m', watch=True)
    def update(self):
        print(self.m)

p = P()
# Does NOT trigger `update`
P.m = 10
print(p.m)
# 10

maximlt avatar Jun 27 '23 15:06 maximlt

I have a brief (late) look at this issue, I'm not sure how to trigger the callbacks of all the instances of a class when a watched Parameter is updated at the class level. @jbednar @philippjfr interested in your opinion and if it's worth spending time on this to get it in Param 2.0.

maximlt avatar Jul 26 '23 00:07 maximlt

Yeah, this is awkward to fix. The only way to get all instances would be to keep (weak) references to all instances of a class or iterating over all objects in gc.get_objects(). Both of which seem less than ideal, although I can vaguely imagine the weakref approach. I'd say we skip this one for now.

philippjfr avatar Jul 26 '23 11:07 philippjfr