I’ve got a parameterized class that’s nested in a parameterized class, and I’d like to listen to changes in an attribute of that nested class. Basically in the MWE below, when I change foo
I’d like the Markdown pane to update. Of course I can’t directly listen to foo
as that’s not a parameter on B
.
I’ve toyed around a bit with various variations on the below but to no avail. Does anyone have an idea? Thanks!
import param
import panel as pn
pn.extension()
class A(param.Parameterized):
foo = param.Integer()
class B(param.Parameterized):
a = param.ClassSelector(A)
bar = param.Integer()
class Viewer(B):
@param.depends('a', 'bar')
def controls(self):
return pn.Param(self.a, parameters=['foo'])
@param.depends('a', 'bar')
def view(self):
return pn.pane.Markdown(f'Sum: {self.a.foo+self.bar+2}')
a = A()
v = Viewer(a=a)
pn.Row(v.controls, v.view)
1 Like
E.g. something like the below seems to trigger the update in A but still nothing happens in B:
import param
import copy
class A(param.Parameterized):
foo = param.Integer()
class B(param.Parameterized):
a = param.ClassSelector(A)
bar = param.Integer()
class TriggerA(A):
@param.depends('foo', watch=True)
def _update(self):
print('Updating...')
self = copy.copy(self)
class Viewer(B):
@param.depends('a', 'bar', watch=True)
def controls(self):
return pn.Param(self.a, parameters=['foo'])
@param.depends('a', 'bar', watch=True)
def view(self):
return pn.pane.Markdown(f'Sum: {self.a.foo+self.bar+2}')
a = TriggerA()
v = Viewer(a=a)
pn.Row(v.controls, v.view)
Listening to ‘a’ will only trigger updates when the entire object is swapped out but you can listen to specific parameters on the sub-object by using the ‘parameterized.parameter’ syntax, e.g. in your case that would be:
@param.depends('a.foo', 'bar')
def view(self):
return pn.pane.Markdown(f'Sum: {self.a.foo+self.bar+2}')
As an aside, do not use watch=True on a function which returns something like in your second example. This will start warning in the next release.
1 Like
Thanks, also for the watch=True heads up!
1 Like