Skip to content

Commit

Permalink
Add a dedicated namespace for private objs on Parameterized (#766)
Browse files Browse the repository at this point in the history
  • Loading branch information
maximlt authored Jul 11, 2023
1 parent 6b50168 commit fba848e
Show file tree
Hide file tree
Showing 7 changed files with 316 additions and 102 deletions.
14 changes: 7 additions & 7 deletions examples/user_guide/How_Param_Works.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"source": [
"class Count:\n",
" def __init__(self, start=0):\n",
" self._count=start\n",
" self._count = start\n",
" \n",
" def __get__(self, obj, objtype=None):\n",
" self._count += 1\n",
Expand Down Expand Up @@ -89,7 +89,7 @@
"\n",
"- allowing Parameter default values to be set at the class level (as just described),\n",
"- supporting inheriting Parameter objects from superclasses, \n",
"- instantiating parameter default values into the class's dictionary (if needed)\n",
"- instantiating parameter default values (if needed)\n",
"- populating the `name` slot of each Parameter by its attribute name in the class,\n",
"- reporting whether a class has been declared to be abstract (useful for ignoring it in selectors),\n",
"- various bookkeeping about dependencies and watchers, \n",
Expand Down Expand Up @@ -175,7 +175,7 @@
"id": "36ef8c10",
"metadata": {},
"source": [
"If the value of `p` is set on `a1`, `a1`'s value of `p` is stored in the `a1` instance itself, under a specially mangled attribute name. The mangled name is called the `_internal_name` of the parameter, and is constructed from the \"attrib name\" of the parameter (i.e. `p` in this case) but modified so that it will not be confused with the underlying `Parameter` object `p`:"
"If the value of `p` is set on `a1`, `a1`'s value of `p` is stored in the `a1` instance itself, in a dictionary named `values` under the private namespace `_param__private`:"
]
},
{
Expand All @@ -185,16 +185,16 @@
"metadata": {},
"outputs": [],
"source": [
"a1.p=2\n",
"a1.__dict__['_p_param_value']"
"a1.p = 2\n",
"a1._param__private.values['p']"
]
},
{
"cell_type": "markdown",
"id": "9b5c6a79",
"metadata": {},
"source": [
"When `a1.p` is requested, `a1.__dict__['_p_param_value']` is returned. When `a2.p` is requested, `_p_param_value` is not found in `a2.__dict__`, so `A.__dict__['p'].default` (i.e. `A.p`) is returned instead:"
"When `a1.p` is requested, `a1._param__private.values['p']` is returned. When `a2.p` is requested, `p` is not found in `a2._param__private.values`, so `A.__dict__['p'].default` (i.e. `A.p`) is returned instead:"
]
},
{
Expand Down Expand Up @@ -222,7 +222,7 @@
"metadata": {},
"outputs": [],
"source": [
"A.p=3\n",
"A.p = 3\n",
"a2.p, a1.p"
]
},
Expand Down
66 changes: 65 additions & 1 deletion examples/user_guide/Parameters.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -897,14 +897,78 @@
"p.param.pprint()"
]
},
{
"cell_type": "markdown",
"id": "3830ace8",
"metadata": {},
"source": [
"## Parameterized namespace\n",
"\n",
"Param allows you to create Parameterized objects by inheriting from the `Parameterized` base class. Param has evolved over time to reduce its footprint and reserve as few as possible attributes on this namespace, to reduce the risk of name clashes and allow you to freely define your attribute names. Param reserves a few names that are described below, make sure not to override, unless it is stated it is allowed:\n",
"\n",
"- Public attributes:\n",
" - `name`: Parameterized classes and instances have a name `String` Parameter, that by default is set to the class name when accessed from the class and to the class name appended with a 5 digit when accessed from the instance. You can override this Parameter by your own `String` Parameter if you need to.\n",
" - `param`: Property that helps keep the Parameterized namespace clean and disambiguate between Parameter objects and parameter values, it gives access to a namespace that offers various methods (see the section below) to update and inspect the Parameterized object at hand.\n",
"- Private attributes:\n",
" - `_param__parameters`: Store the object returned by `.param` on the class\n",
" - `_param__private`: Store various internal data on Parameterized class and instances\n",
" - `_param_watchers` (to be removed soon): Store a dictionary of instance watchers"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "01759e1b",
"metadata": {},
"outputs": [],
"source": [
"class P(param.Parameterized):\n",
" a = param.Number()\n",
" b = param.String()\n",
"\n",
"p = P()\n",
"print(f'{P.name=}, {p.name=}')"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e802c7c7",
"metadata": {},
"outputs": [],
"source": [
"def namespace(obj):\n",
" return [o for o in dir(obj) if not o.startswith('__')]"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5c702205",
"metadata": {},
"outputs": [],
"source": [
"namespace(P)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b74fb157",
"metadata": {},
"outputs": [],
"source": [
"namespace(p)"
]
},
{
"cell_type": "markdown",
"id": "23979d82",
"metadata": {},
"source": [
"## Other Parameterized methods\n",
"\n",
"Like `.param.pprint`, the remaining \"utility\" or convenience methods available for a `Parameterized` class or object are provided via a subobject called `param` that helps keep the namespace clean and disambiguate between Parameter objects and parameter values:\n",
"Like `.param.pprint`, the remaining \"utility\" or convenience methods available for a `Parameterized` class or object are provided via the `.param` subobject:\n",
"\n",
"- `.param.update(**kwargs)`: Set parameter values from the given `param=value` keyword arguments (or a dict or iterable), delaying watching and dependency handling until all have been updated. `.param.update` can also be used as a context manager to temporarily set values, that are restored to their original values when the context manager exits."
]
Expand Down
2 changes: 1 addition & 1 deletion param/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2967,7 +2967,7 @@ def _reset_event(self, obj, val):
if obj is None:
self.default = val
else:
obj.__dict__[self._internal_name] = val
obj._param__private.values[self.name] = val
self._post_setter(obj, val)

@instance_descriptor
Expand Down
Loading

0 comments on commit fba848e

Please sign in to comment.