# What is the best way to define nested Parameters in Parameterized class

**URL:** <https://discourse.holoviz.org/t/what-is-the-best-way-to-define-nested-parameters-in-parameterized-class/2733>\
**Category:** Param\
**Created:** [August 29, 2021, 9:56pm UTC](https://discourse.holoviz.org/t/what-is-the-best-way-to-define-nested-parameters-in-parameterized-class/2733 "2021-08-29T21:56:59Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Illia](https://discourse.holoviz.org/letter_avatar_proxy/v4/letter/i/e79b87/32.png) [@Illia](https://discourse.holoviz.org/u/Illia)\
**Post date:** [August 29, 2021, 9:56pm UTC](https://discourse.holoviz.org/t/what-is-the-best-way-to-define-nested-parameters-in-parameterized-class/2733/1 "2021-08-29T21:56:59Z")

</div>

First approach:

- is to create separate Parameterized classes

```auto
import param as pm

class B(pm.Parameterized):
    class A(pm.Parameterized):
        a = pm.Integer(10)
        b = pm.Number(0)
    
    a = A()
    b = pm.Integer(50)
    
    def __init__ (self, **params):
        super(). __init__ (**params)
        
    @pm.depends("a.a", watch=True)
    def callback(self):
        print(self.a.a * 10)

```

Second approach:  
- as Class Selector

```auto
import param as pm

class B(pm.Parameterized):
    class A(pm.Parameterized):
        a = pm.Integer(10)
        b = pm.Number(0)
    
    a = pm.ClassSelector(class_=A, default=A())
    b = pm.Integer(50)
    
    def __init__ (self, **params):
        super(). __init__ (**params)
        
    @pm.depends("a.param", watch=True)
    def callback(self):
        print(self.a.a * 10)

```

Maybe there are another approaches?  
What difference between them?

---

<div class="post-metadata">

**Author:** ![Illia](https://discourse.holoviz.org/letter_avatar_proxy/v4/letter/i/e79b87/32.png) [@Illia](https://discourse.holoviz.org/u/Illia)\
**Post date:** [August 29, 2021, 10:09pm UTC](https://discourse.holoviz.org/t/what-is-the-best-way-to-define-nested-parameters-in-parameterized-class/2733/2 "2021-08-29T22:09:52Z")

</div>

The aim of nested parameters is to create something similar to nested dicts (or nested configs)

---

<div class="post-metadata">

**Author:** ![Marc](https://discourse.holoviz.org/user_avatar/discourse.holoviz.org/marc/32/24_2.png) [@Marc](https://discourse.holoviz.org/u/Marc)\
**Post date:** [August 30, 2021, 4:05am UTC](https://discourse.holoviz.org/t/what-is-the-best-way-to-define-nested-parameters-in-parameterized-class/2733/3 "2021-08-30T04:05:11Z")

</div>

Hi @Illia

I’ve would do something close to your second approach.

```python
import param as pm

class X(pm.Parameterized):
        a = pm.Integer(10)
        b = pm.Number(0)

class Y(pm.Parameterized):
    c = pm.ClassSelector(class_=X)
    d = pm.Integer(50)

    def __init__ (self, **params):
        if not "c" in params:
            params["c"]=X()

        super(). __init__ (**params)

    @pm.depends("c.param", watch=True)
    def callback(self):
        self.d+=1
        print("c", self.c.a, self.c.b)
        print("d", self.d)

```

If I add the `test_case` below to the script

```python
def test_case():
    y=Y()
    for _ in range(0,2):
        y.c.a+=1
        y.c.b+=1

test_case()

```

and run `python name_of_script.py` I see

```bash
c 11 0
d 51
c 11 1
d 52
c 12 1
d 53
c 12 2
d 54

```

---

<div class="post-metadata">

**Author:** ![Marc](https://discourse.holoviz.org/user_avatar/discourse.holoviz.org/marc/32/24_2.png) [@Marc](https://discourse.holoviz.org/u/Marc)\
**Post date:** [August 30, 2021, 4:09am UTC](https://discourse.holoviz.org/t/what-is-the-best-way-to-define-nested-parameters-in-parameterized-class/2733/4 "2021-08-30T04:09:42Z")

</div>

For further inspiration check out the [Param subobjects](https://panel.holoviz.org/gallery/param/param_subobjects.html#param-gallery-param-subobjects) notebook.

[/uploads/default/original/2X/a/a9fe90c26b571fc3e23f7e181ae31d5b33e6ffda.mp4](https://discourse.holoviz.org/uploads/default/original/2X/a/a9fe90c26b571fc3e23f7e181ae31d5b33e6ffda.mp4)

---

<div class="post-metadata">

**Author:** ![Illia](https://discourse.holoviz.org/letter_avatar_proxy/v4/letter/i/e79b87/32.png) [@Illia](https://discourse.holoviz.org/u/Illia)\
**Post date:** [August 31, 2021, 6:51pm UTC](https://discourse.holoviz.org/t/what-is-the-best-way-to-define-nested-parameters-in-parameterized-class/2733/5 "2021-08-31T18:51:28Z")

</div>

Oh, I missed this notebook.  
Thank you

---

<div class="post-metadata">

**Author:** ![Alexboiboi](https://discourse.holoviz.org/user_avatar/discourse.holoviz.org/alexboiboi/32/336_2.png) [@Alexboiboi](https://discourse.holoviz.org/u/Alexboiboi)\
**Post date:** [November 7, 2021, 3:19pm UTC](https://discourse.holoviz.org/t/what-is-the-best-way-to-define-nested-parameters-in-parameterized-class/2733/6 "2021-11-07T15:19:42Z")

</div>

Hi @Alexboiboi

A general solution is something that is discussed here [Full JSON/YAML support for Param · Issue #520 ·](https://github.com/holoviz/param/issues/520).

If you provide a specific example we could for sure find a concrete solution.

---

<div class="post-metadata">

**Author:** ![Alexboiboi](https://discourse.holoviz.org/user_avatar/discourse.holoviz.org/alexboiboi/32/336_2.png) [@Alexboiboi](https://discourse.holoviz.org/u/Alexboiboi)\
**Post date:** [November 9, 2021, 2:03pm UTC](https://discourse.holoviz.org/t/what-is-the-best-way-to-define-nested-parameters-in-parameterized-class/2733/7 "2021-11-09T14:03:22Z")

</div>

Hi @Marc,

thank you for your response.

I am currently working on a project where some graphical styling properties can be set by a user. So far I implemented a bunch of classes with setters and getters with some validation. It works but its is very verbose and with the `param` library I was hoping to make the code cleaner and later make the step to implement the parametrization via some GUI much simpler.

---

<div class="post-metadata">

**Author:** ![Alexboiboi](https://discourse.holoviz.org/user_avatar/discourse.holoviz.org/alexboiboi/32/336_2.png) [@Alexboiboi](https://discourse.holoviz.org/u/Alexboiboi)\
**Post date:** [November 9, 2021, 3:48pm UTC](https://discourse.holoviz.org/t/what-is-the-best-way-to-define-nested-parameters-in-parameterized-class/2733/8 "2021-11-09T15:48:43Z")

</div>

Ideally I would like to do something like:

```python
import param

class Description(param.Parameterized):
    show = param.Boolean(default=None, allow_None=True)
    text = param.String()

class BaseStyle(param.Parameterized):
    displayname = param.String(default=None, allow_None=True)
    description = param.ClassSelector(Description, default=Description())
    
new_values = {
    "displayname": "some name",
    "description": {"show":True, "text":"some text"}
}

bs = BaseStyle()

# then update the `BaseStyle` class with a nested dictionary
bs.param.update(**new_values)

```

---

<div class="post-metadata">

**Author:** ![Alexboiboi](https://discourse.holoviz.org/user_avatar/discourse.holoviz.org/alexboiboi/32/336_2.png) [@Alexboiboi](https://discourse.holoviz.org/u/Alexboiboi)\
**Post date:** [November 25, 2021, 10:02pm UTC](https://discourse.holoviz.org/t/what-is-the-best-way-to-define-nested-parameters-in-parameterized-class/2733/9 "2021-11-25T22:02:43Z")

</div>

Hi @Marc , do you have any suggestions?

---

<div class="post-metadata">

**Author:** ![maximlt](https://discourse.holoviz.org/user_avatar/discourse.holoviz.org/maximlt/32/2487_2.png) [@maximlt](https://discourse.holoviz.org/u/maximlt)\
**Post date:** [November 26, 2021, 8:50am UTC](https://discourse.holoviz.org/t/what-is-the-best-way-to-define-nested-parameters-in-parameterized-class/2733/10 "2021-11-26T08:50:42Z")

</div>

Hi @Alexboiboi !

Well I _think_ that the `.update` method doesn’t allow you to update nested Parameters like that. It may be worthwhile opening a feature request (if there isn’t one already!) to see what the core devs think about it.

In the mean time you could try to use this function that takes a parameterized object and a nested dict and update each one of the parameters declared in the nested dict:

```python
def update_with_nested_dict(parameterized, nested_dict):
    # Using `batch_call_watchers` because it has the same underlying
    # mechanism as with `param.update`
    # See https://param.holoviz.org/user_guide/Dependencies_and_Watchers.html?highlight=batch_call#batch-call-watchers
    with param.parameterized.batch_call_watchers(parameterized):
        for pname, value in nested_dict.items():
            if isinstance(getattr(parameterized, pname), param.Parameterized):
                if not isinstance(value, dict):
                    raise ValueError(
                        f'The nested parameterized parameter "{pname}" must be '
                        f'updated with a dictionary, not a {type(value). __name__ }.')
                update_with_nested_dict(getattr(parameterized, pname), value)
            else:
                setattr(parameterized, pname, value)

```

And use it as follows:

```python
update_with_nested_dict(bs, new_values)

```

I’ve just tried this function quickly on a simple example and it worked, but Param is a complex machinery so if you use that function in your code try to make sure it works as you expect.

---

<div class="post-metadata">

**Author:** ![Alexboiboi](https://discourse.holoviz.org/user_avatar/discourse.holoviz.org/alexboiboi/32/336_2.png) [@Alexboiboi](https://discourse.holoviz.org/u/Alexboiboi)\
**Post date:** [December 1, 2021, 3:34pm UTC](https://discourse.holoviz.org/t/what-is-the-best-way-to-define-nested-parameters-in-parameterized-class/2733/11 "2021-12-01T15:34:58Z")

</div>

@maximlt thank you very much for your response. I’ll try this out

---

<div class="post-metadata">

**Author:** ![JonathanMair](https://discourse.holoviz.org/user_avatar/discourse.holoviz.org/jonathanmair/32/4881_2.png) [@JonathanMair](https://discourse.holoviz.org/u/JonathanMair)\
**Post date:** [May 11, 2023, 7:09pm UTC](https://discourse.holoviz.org/t/what-is-the-best-way-to-define-nested-parameters-in-parameterized-class/2733/12 "2023-05-11T19:09:46Z")

</div>

this question bears on the topic of this post…

> [@Accessing parameters of nested parameterized objects when displaying in panel](https://discourse.holoviz.org/t/accessing-parameters-of-nested-parameterized-objects-when-displaying-in-panel/5338):
>
> Hi All I’m quite new to panel and param and really like them. I’m trying to build an app that will be based on a moderately complicated data model, which I’m building in parameterized classes. These classes will sometimes be nested at various levels, but they should work independently too. This seems to be to be a very natural use case. I’ve expressed it quite abstractly, but for instance, if you have a Recipe object, it might have a list of Ingredient objects, and you might want to be able to …
