code: def __call__(self, alt):
      bn_name = alt.__name__
  
      try:
          bn_func = getattr(bn, bn_name)
      except (AttributeError, NameError):  # pragma: no cover
          bn_func = None
  
      @functools.wraps(alt)
      def f(values, axis=None, skipna=True, **kwds):
          if len(self.kwargs) > 0:
              for k, v in compat.iteritems(self.kwargs):
                  if k not in kwds:
                      kwds[k] = v
          try:
              if values.size == 0 and kwds.get("min_count") is None:
                  # We are empty, returning NA for our type
                  # Only applies for the default `min_count` of None
                  # since that affects how empty arrays are handled.
                  # TODO(GH-18976) update all the nanops methods to
                  # correctly handle empty inputs and remove this check.
                  # It *may* just be `var`
                  return _na_for_min_count(values, axis)
  
              if (
                  _USE_BOTTLENECK
                  and skipna
                  and _bn_ok_dtype(values.dtype, bn_name)
              ):
                  result = bn_func(values, axis=axis, **kwds)
  
                  # prefer to treat inf/-inf as NA, but must compute the func
                  # twice :(
                  if _has_infs(result):
                      result = alt(
                          values, axis=axis, skipna=skipna, **kwds
                      )
              else:
                  result = alt(values, axis=axis, skipna=skipna, **kwds)
          except Exception:
              try:
                  result = alt(values, axis=axis, skipna=skipna, **kwds)
              except ValueError as e:
                  # we want to transform an object array
                  # ValueError message to the more typical TypeError
                  # e.g. this is normally a disallowed function on
                  # object arrays that contain strings
  
                  if is_object_dtype(values):
                      raise TypeError(e)
                  raise
  
          return result
  
      return f
  
imports: from distutils.version import LooseVersion
  import functools
  import itertools
  import operator
  import warnings
  import numpy
  from pandas._libs import iNaT, lib, tslibs
  import pandas.compat
  from pandas.core.dtypes.cast import _int64_max, maybe_upcast_putmask
  from pandas.core.dtypes.common import _get_dtype, is_any_int_dtype, is_bool_dtype, is_complex, is_complex_dtype, is_datetime64_dtype, is_datetime64tz_dtype, is_datetime_or_timedelta_dtype, is_float, is_float_dtype, is_integer, is_integer_dtype, is_numeric_dtype, is_object_dtype, is_scalar, is_timedelta64_dtype, pandas_dtype
  from pandas.core.dtypes.dtypes import DatetimeTZDtype
  from pandas.core.dtypes.missing import isna, na_value_for_dtype, notna
  import pandas.core.common
  from pandas.core.config import get_option
label_desc: Use image node_id 2 for calling the bottleneck_switch obj's underlying member method code with example usage: obj.__call__(alt) and returns: f, result, _na_for_min_count