Issues when iterating through all params in a parameterized class

Hello there,

I’m new to param and panel and would appreciate help on how to access and set params in a class:

Basically, when iterating through the parameters of an unknown parameterized class (I have lots of them and want to automate it), the most intuitive ways of accessing and resetting params are not working, shown below in the code with issues as comments. Any help would be much appreciated!

import param

class TestClass(param.Parameterized):

    param1 = param.String(default="abc")
    param2 = param.String(default="def")
    param3 = param.String(default="ghi")


    def __init__(self, **params):
        super().__init__(**params)
        print("{} initialised".format(self.name))

test_obj = TestClass()

test_obj.param1 = "ABC"                      # editing a named param works fine

# in the for loop, each line is attempting to do the same thing.
for x in test_obj.param:
    if not x == "name":
        test_obj.x = "new text"              # sets an actual parameter 'x' to the value
        test_obj.param[x] = "new text"       # TypeError: 'Parameters' object does not support item assignment
        test_obj.__setattr__(x, "new text")  # does work
        setattr(test_obj, x, "new text")     # does work


for y in test_obj.param:
    print(getattr(test_obj, y))              # does work
    print(test_obj.y)                        # returns AttributeError: 'TestClass' object has no attribute 'y'

Some guidance:

  • always GET and SET Parameter VALUES as you’d set/get normal attributes on a normal class

  • To get a list of all Parameter NAMES and OBJECTS a parameterized class has defined, use the xxx.param.objects() because it makes clear what you’re getting

  • Access Parameter OBJECTS to read/change things like defaults, … value ranges, … etc … things that define how the Parameter/attribute behaves

  • using the .param namespace is usually only for getting access to the Parameter objects/names, not values (ignoring xxx.param.values())

2 Likes

I agree. The below should be the way to achieve what you want

import param

class TestClass(param.Parameterized):

    param1 = param.String(default="abc")
    param2 = param.String(default="def")
    param3 = param.String(default="ghi")


    def __init__(self, **params):
        super().__init__(**params)
        print("{} initialised".format(self.name))

test_obj = TestClass()

test_obj.param1 = "ABC"                      # editing a named param works fine

for x in test_obj.param:
    if not x == "name":
        setattr(test_obj, x, "new text")     # does work
        

for y in test_obj.param:
    print(getattr(test_obj, y))              # does work

The command print(test_obj.y) will not work as you are trying to print the attribute named "y" which does not exist.

Thanks guys!