Meta decorator with parameters, defined in explicit functions

Lawrence D’Oliveiro lawrencedo99 at gmail.com
Wed Jun 29 22:43:04 EDT 2016


On Tuesday, June 28, 2016 at 5:03:08 PM UTC+12, Ben Finney wrote:
> There is a clever one-line decorator that has been copy-pasted without
> explanation in many code bases for many years::
> 
>     decorator_with_args = lambda decorator: lambda *args, **kwargs: lambda func: decorator(func, *args, **kwargs)
> 
> My problem with this is precisely that it is clever: it explains nothing
> about what it does, has many moving parts that are not named, it is
> non-obvious and lacks expressiveness.

It is written in a somewhat roundabout way: why not just

    decorator_with_args = lambda decorator, *args, **kwargs : lambda func : decorator(func, *args, **kwargs)

? Could it be this was not valid in earlier versions of Python?

Anyway, it’s a function of a function returning a function. Example use (off the top of my head):

    my_decorator = decorator_with_args(actual_func_to_call)(... remaining args for actual_func_to_call)

(for the original version) or

    my_decorator = decorator_with_args(actual_func_to_call,... remaining args for actual_func_to_call)

(for the simpler version). Then an example use would be

    @my_decorator
    def some_func...

which would call “actual_func_to_call” with some_func plus all those extra args, and assign the result back to some_func.

> I would like to see a more Pythonic, more explicit and expressive
> replacement with its component parts easily understood.

I don’t know why this fear and suspicion of lambdas is so widespread among Python users ... former Java/C# programmers, perhaps?


More information about the Python-list mailing list