Run parameterized class function on instantiation

There seems to be no dedicated param category so I am putting this here.

What would be the canonical way to get my instance of Test to automatically calculate b on instantiation?

Note that I prefer leaving the calculation of b outside of .view because b might be accessed from more than one function.

import param
import panel as pn
pn.extension()

class Test(param.Parameterized):
    a = param.Integer(default=0, bounds=(0, 10))
    
    @param.depends('a', watch=True)
    def get_b(self):
        self.b = self.a *2
        
    @param.depends('a')
    def view(self):
        return pn.pane.Markdown(f'{self.a} * 2 = {self.b}')
   
test = Test()
test.get_b() # I would like to get rid of this line
pn.Column(test.param, test.view)

You can do any initialization you like by defining a constructor __init__.py for Test:

import param
import panel as pn
pn.extension()

class Test(param.Parameterized):
    a = param.Integer(default=0, bounds=(0, 10))

    def __init__(self,**params):
        super(Test,self).__init__(**params)
        self.get_b()
    
    @param.depends('a', watch=True)
    def get_b(self):
        self.b = self.a *2
        
    @param.depends('a')
    def view(self):
        return pn.pane.Markdown(f'{self.a} * 2 = {self.b}')
   
test = Test()
pn.Column(test.param, test.view)

Ah, of course, thanks! I guess I was low-key expecting some param decorator.

1 Like

If you plan to always instantiate Test objects without arguments (test = Test()), you could probably write:

import param
import panel as pn
pn.extension()

class Test(param.Parameterized):
    a = param.Integer(default=0, bounds=(0, 10))
    b = param.Integer(default=a.default*2, bounds=(0, 20))
    
    @param.depends('a', watch=True)
    def update_b(self):
        self.b = self.a *2
        
    @param.depends('a')
    def view(self):
        return pn.pane.Markdown(f'{self.a} * 2 = {self.b}')
   
test = Test()
pn.Column(test.param, test.view)