docs: def get_node(self, *node_ids, node_attr=NONE):
          """
          Returns a sub node of a dispatcher.
  
          :param node_ids:
              A sequence of node ids or a single node id. The id order identifies
              a dispatcher sub-level.
          :type node_ids: str
  
          :param node_attr:
              Output node attr.
  
              If the searched node does not have this attribute, all its
              attributes are returned.
  
              When 'auto', returns the "default" attributes of the searched node,
              which are:
  
                - for data node: its output, and if not exists, all its
                  attributes.
                - for function and sub-dispatcher nodes: the 'function' attribute.
  
              When 'description', returns the "description" of the searched node,
              searching also in function or sub-dispatcher input/output
              description.
  
              When 'output', returns the data node output.
  
              When 'default_value', returns the data node default value.
  
              When 'value_type', returns the data node value's type.
  
              When `None`, returns the node attributes.
          :type node_attr: str, None, optional
  
          :return:
              Node attributes and its real path.
          :rtype: (T, (str, ...))
  
          **Example**:
  
          .. dispatcher:: o
             :opt: graph_attr={'ratio': '1'}, depth=-1
  
              >>> import schedula as sh
              >>> sub_dsp = sh.Dispatcher(name='Sub-dispatcher')
              >>> def fun(a, b):
              ...     return a + b
              ...
              >>> sub_dsp.add_function('a + b', fun, ['a', 'b'], ['c'])
              'a + b'
              >>> dispatch = sh.SubDispatch(sub_dsp, ['c'], output_type='dict')
              >>> dsp = sh.Dispatcher(name='Dispatcher')
              >>> dsp.add_function('Sub-dispatcher', dispatch, ['a'], ['b'])
              'Sub-dispatcher'
  
              >>> o = dsp.dispatch(inputs={'a': {'a': 3, 'b': 1}})
              ...
  
          Get the sub node output::
  
              >>> dsp.get_node('Sub-dispatcher', 'c')
              (4, ('Sub-dispatcher', 'c'))
              >>> dsp.get_node('Sub-dispatcher', 'c', node_attr='type')
              ('data', ('Sub-dispatcher', 'c'))
  
          .. dispatcher:: sub_dsp
             :opt: workflow=True, graph_attr={'ratio': '1'}
             :code:
  
              >>> sub_dsp, sub_dsp_id = dsp.get_node('Sub-dispatcher')
          """
          kw = {}
  
          from .sol import Solution
          if node_attr is NONE:
              node_attr = 'output' if isinstance(self, Solution) else 'auto'
  
          if isinstance(self, Solution):
              kw['solution'] = self
  
          from .alg import get_sub_node
          dsp = getattr(self, 'dsp', self)
  
          # Returns the node.
          return get_sub_node(dsp, node_ids, node_attr=node_attr, **kw)