.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/recipies/_03_composite_objects.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_recipies__03_composite_objects.py: .. _compositeobjects: Composite-Algorithms and Pipelines ================================== Sometimes a pipeline or algorithms requires a list of parameters or nested objects. As we can not support parameters which names are not known when the class is defined, such cases need to be handled via composite fields. A composite field is a parameter expecting a value of the shape `[(name1, sub_para1), (name2, sub_para2), ...]`. The sub-paras can themselves be tpcp objects. As it is difficult at runtime to know, if a parameter is expected to be a composite field, you need to actively specify all fields that should be considered composite fields during class definition using the `_composite_params` attribute: .. GENERATED FROM PYTHON SOURCE LINES 18-37 .. code-block:: default import dataclasses import traceback from typing import Optional from tpcp import Pipeline from tpcp.exceptions import ValidationError @dataclasses.dataclass class Workflow(Pipeline): _composite_params = ("pipelines",) pipelines: Optional[list[tuple[str, Pipeline]]] = None def __init__(self, pipelines=None): self.pipelines = pipelines .. GENERATED FROM PYTHON SOURCE LINES 38-42 That's it! Now tpcp knows, that `pipelines` should be a composite field and will actually complain, if we try to assign something invalid. Composite fields are allowed to either have the value None, or be a list of tuples as explained above .. GENERATED FROM PYTHON SOURCE LINES 42-45 .. code-block:: default instance = Workflow() instance.pipelines # Our default value of None .. GENERATED FROM PYTHON SOURCE LINES 46-53 .. code-block:: default instance.pipelines = "something invalid" try: print(instance.get_params()) except ValidationError: traceback.print_exc() .. rst-class:: sphx-glr-script-out .. code-block:: none Traceback (most recent call last): File "/home/docs/checkouts/readthedocs.org/user_builds/tpcp/checkouts/v2.2.0/examples/recipies/_03_composite_objects.py", line 48, in print(instance.get_params()) File "/home/docs/checkouts/readthedocs.org/user_builds/tpcp/checkouts/v2.2.0/src/tpcp/_base.py", line 426, in get_params return _get_params(self, deep) File "/home/docs/checkouts/readthedocs.org/user_builds/tpcp/checkouts/v2.2.0/src/tpcp/_base.py", line 556, in _get_params _assert_is_allowed_composite_value(v, key, i) File "/home/docs/checkouts/readthedocs.org/user_builds/tpcp/checkouts/v2.2.0/src/tpcp/_base.py", line 512, in _assert_is_allowed_composite_value raise ValidationError( tpcp.exceptions.ValidationError: The provided parameters for the composite field pipelines does not seem to be the right type. It should be a sequence of `(name, value)` tuples, but the obj at position 0 in the sequence was not a tuple but: `s` .. GENERATED FROM PYTHON SOURCE LINES 54-56 While you could set the individual sub-params in a composite field to whatever you want, the real value of explicit composite fields are the use of tpcp-objects .. GENERATED FROM PYTHON SOURCE LINES 56-65 .. code-block:: default @dataclasses.dataclass class MyPipeline(Pipeline): param: float = 4 param2: int = 10 workflow_instance = Workflow( pipelines=[("pipe1", MyPipeline()), ("pipe2", MyPipeline(param2=5))] ) .. GENERATED FROM PYTHON SOURCE LINES 66-67 We can now use `get_params` to get a deep inspection of the nested objects: .. GENERATED FROM PYTHON SOURCE LINES 67-69 .. code-block:: default workflow_instance.get_params(deep=True) .. rst-class:: sphx-glr-script-out .. code-block:: none {'pipelines__pipe1': MyPipeline(param=4, param2=10), 'pipelines__pipe1__param': 4, 'pipelines__pipe1__param2': 10, 'pipelines__pipe2': MyPipeline(param=4, param2=5), 'pipelines__pipe2__param': 4, 'pipelines__pipe2__param2': 5, 'pipelines': [('pipe1', MyPipeline(param=4, param2=10)), ('pipe2', MyPipeline(param=4, param2=5))]} .. GENERATED FROM PYTHON SOURCE LINES 70-71 Or we can set params using the following syntax: .. GENERATED FROM PYTHON SOURCE LINES 71-76 .. code-block:: default workflow_instance = workflow_instance.set_params( pipelines__pipe1__param=2, pipelines__pipe2=MyPipeline(param2=4) ) workflow_instance.get_params(deep=True) .. rst-class:: sphx-glr-script-out .. code-block:: none {'pipelines__pipe1': MyPipeline(param=2, param2=10), 'pipelines__pipe1__param': 2, 'pipelines__pipe1__param2': 10, 'pipelines__pipe2': MyPipeline(param=4, param2=4), 'pipelines__pipe2__param': 4, 'pipelines__pipe2__param2': 4, 'pipelines': [('pipe1', MyPipeline(param=2, param2=10)), ('pipe2', MyPipeline(param=4, param2=4))]} .. GENERATED FROM PYTHON SOURCE LINES 77-79 Note that it is not possible to set parameters for keys that don't exist yet! In such a case, you would manually recreate the full list. .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 1.749 seconds) **Estimated memory usage:** 9 MB .. _sphx_glr_download_auto_examples_recipies__03_composite_objects.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: _03_composite_objects.py <_03_composite_objects.py>` .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: _03_composite_objects.ipynb <_03_composite_objects.ipynb>` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_