'Raises an ``AttributeError``if the definition is not callable.
Otherwise returns a list of `Definition` that represents the params.'

@property
@memoize_method
def params(self):

    def get_param_names(context):
        param_names = []
        if (context.api_type == 'function'):
            param_names = list(context.get_param_names())
            if isinstance(context, instance.BoundMethod):
                param_names = param_names[1:]
        elif isinstance(context, (instance.AbstractInstanceContext, er.ClassContext)):
            if isinstance(context, er.ClassContext):
                search = '__init__'
            else:
                search = '__call__'
            names = context.get_function_slot_names(search)
            if (not names):
                return []
            inferred = names[0].infer()
            param_names = get_param_names(next(iter(inferred)))
            if isinstance(context, er.ClassContext):
                param_names = param_names[1:]
            return param_names
        elif isinstance(context, compiled.CompiledObject):
            return list(context.get_param_names())
        return param_names
    followed = list(self._name.infer())
    if ((not followed) or (not hasattr(followed[0], 'py__call__'))):
        raise AttributeError()
    context = followed[0]
    return [_Param(self._evaluator, n) for n in get_param_names(context)]
