def obj_or_id(parameter, param_name, object_types):
    """
    Accepts either an int (or long or str representation of an integer)
    or an object. If it is an int, return it. If it is an object and
    the object is of correct type, return the object's id. Otherwise,
    throw an exception.

    :param parameter: int, str, long, or object
    :param param_name: str
    :param object_types: tuple
    :rtype: int
    """
    from canvasapi.user import User
    try:
        return int(parameter)
    except (ValueError, TypeError):
        if User in object_types and parameter == 'self':
            return parameter
        for obj_type in object_types:
            if isinstance(parameter, obj_type):
                try:
                    return int(parameter.id)
                except Exception:
                    break
        obj_type_list = ','.join([obj_type.__name__ for obj_type in
            object_types])
        message = 'Parameter {} must be of type {} or int.'.format(param_name,
            obj_type_list)
        raise TypeError(message)
