How does one reinitialize a parameter back to its initial settings. For example, suppose I have a parameterized class that represents a user input form and I want to be able to reset it for multiple uses.
import param
import panel as pn
pn.extension()
class Form(param.Parameterized):
""" Imagine a more complex form that tracks user inputs """
my_input = param.String('abc', doc='Help')
class App(param.Parameterized):
""" An application that uses the form"""
form = param.Parameter(Form())
@param.depends('form.my_input')
def render(self):
return pn.Column(
pn.Param(self.form.param),
pn.pane.Markdown(self.form.my_input),
app.param.reinitialize)
def _reinitialize(self):
""" Click me if you want to restart with a new form """
self.form = Form() # This doesn't actually work
self.param.trigger('form')
reinitialize = param.Action(_reinitialize)
# Create a UI
pn.Row(App().render).servable()
Thanks guys. This is a very straight-forward solution, but I missed it because my mental model for how param works is not complete.
It is such a common pattern to update a parameter by assignment to new data of the same type. Assigning to defaults like you did does just that. But why doesn’t that pattern extend to assigning new instances of a parameterized class?
Not being able to articulate the why myself makes me feel like there is a core concept of param that I am missing.
You can also make it work by replacing with a new form. But I felt it became a bit too complicated because the @pn.depends binds to the specific first form. Not any later form.
You will have to use the .watch api instead and first remove the watcher for the old form and then create a new watcher for the new form.
At least that is my understanding ???
But I would also like to understand if there is an easy pattern for resetting by creating a new form.
This is the fundamental problem here, Param should unbind the original Form and rebind the new form on assignment. There’s an issue for this here and I may just tackle this today. I agree that for now you’ll have to fall back to the watch API here and do this manually.