Trigger parameters on instantiation

When parameters are passed as arguments to a class instantiation then they don’t trigger events.

For example:

class Demo(param.Parameterized):
    upper_bound = param.Integer(default=10)
    my_range = param.Range(default=(0, upper_bound.default), bounds=(0, upper_bound.default))
    
    @param.depends('upper_bound', watch=True)
    def update_bounds(self):
        self.param.my_range.bounds = (0, self.upper_bound)
    
    def panel(self):
        return pn.Param(self)

d = Demo(upper_bound=20)
d.panel()

In this example even though upper_bound is passed in the the Demo constructor, it doesn’t trigger the update_bounds method.

One way to ensure that it triggers is to set upper_bound after instantiation:

d = Demo()
d.upper_bound = 20

But is the only way to ensure that the method is triggered on instantiation by calling it in an init method?

class Demo(param.Parameterized):
    upper_bound = param.Integer(default=10)
    my_range = param.Range(default=(0, upper_bound.default), bounds=(0, upper_bound.default))
    
    def __init__(self, **params):
        super().__init__(**params)
        if self.upper_bound != self.param.upper_bound.default:  # Sometimes this matters
            self.update_bounds()
    
    @param.depends('upper_bound', watch=True)
    def update_bounds(self):
        self.param.my_range.bounds = (0, self.upper_bound)
    
    def panel(self):
        return pn.Param(self)

d = Demo(upper_bound=20)
d.panel()

Good question; that actually came up for me today on Promotion Initiative by MarcSkovMadsen · Pull Request #488 · holoviz/param · GitHub. I’m not sure it’s always appropriate to invoke the method in all cases. I wonder if we should add an init=True option to depends, which would execute the dependent method at the end of the __init__ method?