class_docstr: Implements a conditional property using the descriptor protocol.
  
  Using this class to create a decorator will raise an ``AttributeError``
  if none of the delegates (specified in ``delegate_names``) is an attribute
  of the base object or the first found delegate does not have an attribute
  ``attribute_name``.
  
  This allows ducktyping of the decorated method based on
  ``delegate.attribute_name``. Here ``delegate`` is the first item in
  ``delegate_names`` for which ``hasattr(object, delegate) is True``.
  
  See https://docs.python.org/3/howto/descriptor.html for an explanation of
  descriptors.
code: def __get__(self, obj, type=None):
      # raise an AttributeError if the attribute is not present on the object
      if obj is not None:
          # delegate only on instances, not the classes.
          # this is to allow access to the docstrings.
          for delegate_name in self.delegate_names:
              try:
                  delegate = attrgetter(delegate_name)(obj)
              except AttributeError:
                  continue
              else:
                  getattr(delegate, self.attribute_name)
                  break
          else:
              attrgetter(self.delegate_names[-1])(obj)
  
      # lambda, but not partial, allows help() to work with update_wrapper
      out = lambda *args, **kwargs: self.fn(obj, *args, **kwargs)
      # update the docstring of the returned function
      update_wrapper(out, self.fn)
      return out
  
file_path: catboost/contrib/python/scikit-learn/py2/sklearn/utils/metaestimators.py
imports: from operator import attrgetter
  from functools import update_wrapper
  import numpy
  from ..utils import safe_indexing
label_desc: Use image node_id 2 for calling the _IffHasAttrDescriptor obj's underlying member method code with example usage: obj.__get__(obj, type) and returns: out