import six


def get_from_module(identifier,
                    module_params,
                    module_name,
                    instantiate=False,
                    kwargs=None):
  """Retrieves a class of function member of a module.

  Parameters
  ----------
  identifier: the object to retrieve. It could be specified
    by name (as a string), or by dict. In any other case,
    identifier itself will be returned without any changes.
  module_params: the members of a module
    (e.g. the output of globals()).
  module_name: string; the name of the target module. Only used
    to format error messages.
  instantiate: whether to instantiate the returned object
    (if it's a class).
  kwargs: a dictionary of keyword arguments to pass to the
    class constructor if `instantiate` is `True`.

  Returns
  -------
  The target object.

  Raises
  ------
  ValueError: if the identifier cannot be found.
 """
  if isinstance(identifier, six.string_types):
    res = module_params.get(identifier)
    if not res:
      raise ValueError('Invalid ' + str(module_name) + ': ' + str(identifier))
    if instantiate and not kwargs:
      return res()
    elif instantiate and kwargs:
      return res(**kwargs)
    else:
      return res

  return identifier