# Accessing parameters of nested parameterized objects when displaying in panel

**URL:** <https://discourse.holoviz.org/t/accessing-parameters-of-nested-parameterized-objects-when-displaying-in-panel/5338>\
**Category:** Panel\
**Tags:** classselector, param, selector, panel\
**Created:** [May 11, 2023, 6:20pm UTC](https://discourse.holoviz.org/t/accessing-parameters-of-nested-parameterized-objects-when-displaying-in-panel/5338 "2023-05-11T18:20:27Z")\
**Posts on this page:** 15\
**Page:** 1

<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, 6:20pm UTC](https://discourse.holoviz.org/t/accessing-parameters-of-nested-parameterized-objects-when-displaying-in-panel/5338/1 "2023-05-11T18:20:28Z")

</div>

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 handle each of those classes independently of the other some time. I like the declarative nature of param for this kind of task because it means you can declare the relationships between the data/classes and worry about displaying it or not when it comes to the UI.

So to pursue that example, if you’ve got a visualisation based on a Recipe (maybe showing downloads, reviews stats, etc) it could incorporate a tab or pane for focusing on an ingredient. Then the user might select an ingredient using a dropdown (i.e. Selector) and then the relevant pane/panes would update to show the stats for that ingredient.

So my question is how to get the reference to the selected instance in such a way that it can be used as the object that’s visualised in the relevant pane/s.

Displaying the following in panel works as I want (sticking with the Recipe case): recipe\_instance.param — this displays the Selector object with a blue button and the button reveals the instance currently selected with _it’s_ parameterized properties, which can be changed and which persist if you chance the instance using the Selector then change it back.

This is the functionality I want but I don’t want to be limited to displaying everything automatically in one place as with recipe\_instance.param. I want to put the Selector in one place (e.g. sidebar) and the inner class parameters in another place (panes or tabs).

Here is a minimal example to show what I mean and some of the ways I would intuitively think it could be achieved. None of these work. They display the instance of the inner class that is the value of the Selector when the outer class is initiated, but they do not update to another instance if the value of the Selector is changed.

I would be extremely grateful for any pointers—perhaps there’s an obvious way to do this that I’m missing.

```auto
import panel as pn
import param

class Inner(param.Parameterized):
    target_param = param.String(default="default")
    dependent_param = param.String(constant=True)

    @param.depends('target_param', watch=True)
    def _update_dependent_param(self):
        with param.edit_constant(self):
            self.dependent_param = self.target_param

inner1 = Inner(target_param="inner1 parameter")
inner2 = Inner(target_param="inner2 parameter")
inner_objs = [inner1, inner2]

class Outer(param.Parameterized):
    instance_of_Inner = param.Selector(default=inner_objs[0],
                                       objects=inner_objs)

outer = Outer()

references = {
    '(1) outer.param.instance_of_Inner \n\n this is the Selector object that will choose which instance of class Inner is active' : outer.param.instance_of_Inner,
    '(2) outer.instance_of_Inner \n\n this is the value of that Selector object (an instance of Inner) and I would expect it not to update' : outer.instance_of_Inner,
    '(3) outer.instance_of_Inner.param \n\n this should be the instance as a Parameterized object, I would expect this to change reflecting changes in the selection made with the Selector' : outer.instance_of_Inner.param,
    '(4) outer.param \n\n for good measure, to see what calling the Outer as a param object does': outer.param,
    '(5) outer \n\n for good measure, to see what calling the Outer as a value object does': outer,
}

panes = [pn.Column(k, references[k]) for k in references.keys()]
print(panes)
pn.Column(*panes).servable()

```

---

<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:13pm UTC](https://discourse.holoviz.org/t/accessing-parameters-of-nested-parameterized-objects-when-displaying-in-panel/5338/2 "2023-05-11T19:13:37Z")

</div>

PS, to put the question another way:

Searching through previous posts I found a mention of the following example notebook:

[https://panel.holoviz.org/gallery/param/param\_subobjects.html#param-gallery-param-subobjects](https://panel.holoviz.org/gallery/param/param_subobjects.html#param-gallery-param-subobjects)

This nearly does what I want because it has nested classes, but what I need to do is get a live reference to the inner class (i.e. one that updates) through which I can access its parameters as parameters.

In the case of the Subobjects notebook, that would mean getting a reference to the currently selected shape through which one could access, display or modify a parameter of that shape (e.g. line\_width).

---

<div class="post-metadata">

**Author:** ![carl](https://discourse.holoviz.org/user_avatar/discourse.holoviz.org/carl/32/5215_2.png) [@carl](https://discourse.holoviz.org/u/carl)\
**Post date:** [May 12, 2023, 10:29am UTC](https://discourse.holoviz.org/t/accessing-parameters-of-nested-parameterized-objects-when-displaying-in-panel/5338/3 "2023-05-12T10:29:42Z")

</div>

Hi @JonathanMair,

What about something like this from @fdorssers whom made some progress, sounds similar to what you may be looking for though not certain; came across it searching for child classes

[How do you pass a parameter object (from param) to a child class and listen to changes there, and propagate the UI changes back up - Panel - HoloViz Discourse](https://discourse.holoviz.org/t/how-do-you-pass-a-parameter-object-from-param-to-a-child-class-and-listen-to-changes-there-and-propagate-the-ui-changes-back-up/1960)

Thanks, Carl.

---

<div class="post-metadata">

**Author:** ![jbednar](https://discourse.holoviz.org/user_avatar/discourse.holoviz.org/jbednar/32/23_2.png) [@jbednar](https://discourse.holoviz.org/u/jbednar)\
**Post date:** [May 18, 2023, 3:05am UTC](https://discourse.holoviz.org/t/accessing-parameters-of-nested-parameterized-objects-when-displaying-in-panel/5338/4 "2023-05-18T03:05:41Z")

</div>

Are you looking for something like this?

 ![image](https://discourse.holoviz.org/uploads/default/original/2X/d/dce21299c2489ade08a3857ae4bf546d2d64b859.png)

---

<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 20, 2023, 5:02pm UTC](https://discourse.holoviz.org/t/accessing-parameters-of-nested-parameterized-objects-when-displaying-in-panel/5338/5 "2023-05-20T17:02:28Z")

</div>

Thanks for the link Carl — yes, that is indeed what I was looking to do, but I agree with the author of that post that it’s a bit of an unwieldy way of doing it.

---

<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 20, 2023, 5:03pm UTC](https://discourse.holoviz.org/t/accessing-parameters-of-nested-parameterized-objects-when-displaying-in-panel/5338/6 "2023-05-20T17:03:17Z")

</div>

Yes, excellent - thanks!

---

<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 20, 2023, 5:22pm UTC](https://discourse.holoviz.org/t/accessing-parameters-of-nested-parameterized-objects-when-displaying-in-panel/5338/7 "2023-05-20T17:22:59Z")

</div>

Further to @jbednar’s very helpful solution above, this comment for anyone reading this in the same place I was…if you need to access a subset of the params of the inner class then this seems to be one way of doing that…binding the param.objects() function which returns a dictionary of the instance’s Parameter objects, then subscripting to select the one(s) you need, like this:

`pn.bind(lambda x: x.param.objects(instance=True)['target_param'], outer.param.instance_of_Inner)`

---

<div class="post-metadata">

**Author:** ![jbednar](https://discourse.holoviz.org/user_avatar/discourse.holoviz.org/jbednar/32/23_2.png) [@jbednar](https://discourse.holoviz.org/u/jbednar)\
**Post date:** [May 23, 2023, 6:22pm UTC](https://discourse.holoviz.org/t/accessing-parameters-of-nested-parameterized-objects-when-displaying-in-panel/5338/8 "2023-05-23T18:22:09Z")

</div>

Sure, though `.param` provides convenient member-style access, so you can do:

 ![image](https://discourse.holoviz.org/uploads/default/original/2X/d/dc85c5b2b61eefbfa898316737c9e38e2381caf2.png)

---

<div class="post-metadata">

**Author:** ![jbednar](https://discourse.holoviz.org/user_avatar/discourse.holoviz.org/jbednar/32/23_2.png) [@jbednar](https://discourse.holoviz.org/u/jbednar)\
**Post date:** [May 23, 2023, 6:29pm UTC](https://discourse.holoviz.org/t/accessing-parameters-of-nested-parameterized-objects-when-displaying-in-panel/5338/9 "2023-05-23T18:29:36Z")

</div>

If this approach directly meets your needs and wasn’t obvious from the docs, please consider where that would best show up in the Panel (and/or Param?) docs and then file an issue suggesting what to add there, and/or make a PR actually adding that info to the docs!

---

<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 25, 2023, 9:45am UTC](https://discourse.holoviz.org/t/accessing-parameters-of-nested-parameterized-objects-when-displaying-in-panel/5338/10 "2023-05-25T09:45:27Z")

</div>

> Sure, though `.param` provides convenient member-style access

Got it, thanks — in the particular case I was working on, I’m selecting individual parameters of the inner class using a list of strings in order to vary the list it dynamically so the dictionary returned from objects() was useful for that

---

<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 25, 2023, 9:46am UTC](https://discourse.holoviz.org/t/accessing-parameters-of-nested-parameterized-objects-when-displaying-in-panel/5338/11 "2023-05-25T09:46:13Z")

</div>

I will think about it — but at the moment I feel I don’t quite understand it enough!

---

<div class="post-metadata">

**Author:** ![jbednar](https://discourse.holoviz.org/user_avatar/discourse.holoviz.org/jbednar/32/23_2.png) [@jbednar](https://discourse.holoviz.org/u/jbednar)\
**Post date:** [May 25, 2023, 3:32pm UTC](https://discourse.holoviz.org/t/accessing-parameters-of-nested-parameterized-objects-when-displaying-in-panel/5338/12 "2023-05-25T15:32:32Z")

</div>

Right; member-style access is good for hard-coding specific parameters, and the dictionary is good for selecting dynamically. It does take a while to understand how to understand which bits of the code get re-executed automatically and which ones you have to wrap in a lambda or other function to ensure that it’s re-executed when needed. Once that’s clear, improvements to the docs that address the difficulties you encountered would be very helpful, since it’s harder for people who have been using Param for decades to see the best way to describe it for new users!

---

<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 26, 2023, 6:43pm UTC](https://discourse.holoviz.org/t/accessing-parameters-of-nested-parameterized-objects-when-displaying-in-panel/5338/13 "2023-05-26T18:43:45Z")

</div>

Hi - though the above solutions worked in the specific case I was stuck with, I’m still struggling with this general area of passing references through panel.bind. Rather than posting more specific cases, I’m trying to understand the principle and going over the documentation and other posts here. I think I have found my sticking point (or one of them!) now…

I think I’m beginning to understand because of another of your answers, @jbednar ([Get the Values of a Rangeslider - #4 by jbednar](https://discourse.holoviz.org/t/get-the-values-of-a-rangeslider/1186/4)). There you mention that the function part of the pn.bind() wrapper treats a parameter object passed as an argument as an alias for the param _value_.

To apply this to the solution you provided above:

```auto
pn.Row(
    outer, 
    pn.bind(lambda x: x.param, outer.param.instance_of_inner)
)

```

…the `outer.param.instance_of_inner` that is passed into the lambda function is the live parameter object that holds the parameter value (an instance of class Inner). That’s important because if the parameter value is passed instead, that’s just the value at the time the bind() function is called, it won’t be live.

However, inside the function that is the first argument of the bind() call, i.e. in this case the lambda function, the param object that was passed is turned silently into a value. In this case the value of the parameter instance\_of\_inner is a Parameterized class, the lambda function is able to use .param on it to access the parameters of the instance of class Inner.

If this is right then I am finally beginning to understand this behaviour 😅. It makes PERFECT sense because what needs to be watched is the object and what needs to be put into action by the function is the value. However, I am finding it highly counter-intuitive…I guess I’ll get used to it, but I don’t think this is explicitly addressed in the documentation.

---

<div class="post-metadata">

**Author:** ![jbednar](https://discourse.holoviz.org/user_avatar/discourse.holoviz.org/jbednar/32/23_2.png) [@jbednar](https://discourse.holoviz.org/u/jbednar)\
**Post date:** [May 27, 2023, 2:46am UTC](https://discourse.holoviz.org/t/accessing-parameters-of-nested-parameterized-objects-when-displaying-in-panel/5338/14 "2023-05-27T02:46:54Z")

</div>

That’s the behavior of `pn.bind`: it acts exactly like `functools.partial` except that it has special behavior if you pass it a Panel widget or a Parameter object. If you pass a Panel widget, it fetches the Parameter object called `value` that is held by that widget, and acts as if you passed that instead. I.e. passing `widget` is precisely the same as passing `widget.param.value`, which in the common and typical case where you want to watch the `value` (and not the `range` or some other Parameter of the widget) is concise and (to us!) clear.

So whether you passed a widget or a Parameter object, pn.bind has gotten ahold of a Parameter object. It then acts just as if you had passed the Parameter’s value (even though you really passed the Parameter object), _except_ that it is watching the object for changes to the Parameter’s value and it then re-invokes the function with the new value whenever that value changes.

In your case, the Parameter’s value is indeed a Parameterized object (not an individual Parameter object, but a Parameterized object that holds potentially many Parameter objects). So whenever that object changes, the lambda function accesses `.param.instance_of_inner` on the new object, displaying that.

So, pn.bind is what accepts Parameter objects and then invokes the underlying function with the Parameter value, thus bridging between Panel and Param’s world of Parameters and the underlying function’s world of actual values.

I think you’ve got it figured out, but I figured it didn’t hurt to be very specific (unless I misspoke somewhere and made it worse!). If there are changes to the pn.bind docs that could make this clear, i.e. that bind accepts Parameter objects and then invokes the function on Parameter values, please suggest appropriate wording to that effect!

---

<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 29, 2023, 7:53am UTC](https://discourse.holoviz.org/t/accessing-parameters-of-nested-parameterized-objects-when-displaying-in-panel/5338/15 "2023-05-29T07:53:00Z")

</div>

@jbednar – got it, thanks very much for the detailed explanation, that’s very helpful.

I’m still having problems understanding the way param behaves from an OO point of view. Now that I’ve understood pn.bind() better I realise I have other assumptions about it that are proving to be wrong. I will post in the param board because I don’t think it’s on topic any more for this post.

Thanks again!
