code: def recursive_getattr(obj, attr):
      """Get object's attribute. May use dot notation.
  
      >>> class C(object): pass
      >>> a = C()
      >>> a.b = C()
      >>> a.b.c = 4
      >>> recursive_getattr(a, 'b.c')
      4
      """
      if "." not in attr:
          return getattr(obj, attr)
      else:
          L = attr.split(".")
          return recursive_getattr(getattr(obj, L[0]), ".".join(L[1:]))
  
file_path: pytorch-toolbelt/pytorch_toolbelt/optimization/functional.py
imports: import dataclasses
  import numbers
  from typing import Optional, Iterator, Dict, Union, List, Tuple, Mapping
  from torch import nn
  from pytorch_toolbelt.utils.distributed import get_rank, get_world_size, is_dist_avail_and_initialized
  from pytorch_toolbelt.utils.torch_utils import get_non_wrapped_model
label_desc: Use image node_id 2 for calling a global function with example usage: recursive_getattr(obj, attr) and returns: getattr, recursive_getattr