3 ms·
This handles decorators with arguments and makes a general case of passing same arguments to function as to wrapper less cluttered.
by Suor 13y ago
This handles decorators with arguments and makes a general case of passing same arguments to function as to wrapper less cluttered.
- abecedarius 13y agoIt might help to show the same examples from that module's documentation, how they are similar or different. I still don't understand this after a skim of your post, since one example has @decorator def some_decorator(func, args, kwargs): while the next goes @decorator def some_decorator(call): Does this introspect on the parameters of some_decorator? FWIW I'm happy enough with https://github.com/darius/sketchbook/blob/master/misc/decorator.py https://github.com/darius/sketchbook/blob/master/misc/decora...
- Suor 13y agoThe first part of a post is mere reasoning showing how I got to the actual interface I use. @decorator works with `call` not with `func, args, *kwargs`.
- abecedarius 13y agoAh, OK. So there's no way to express an example that needs to get at func, etc.? I think I'd separate out an @decorator that fixes the metadata on the returned function, and another one, using it, that makes a decorator that works on the call() interface.
- zb 13y agoDecorators with arguments are much better handled by classes IMO. This does indeed appear to make that one (common) case of passing the function arguments through unchanged marginally simpler. But it makes every other case worse. Compare, for example: @decorator.decorator def int_args(func, *args): """Coerces any function arguments to ints""" return func(*map(int, args)) to your: @funcy.decorator def int_args(call): """Coerces any function arguments to ints""" return call._func(*map(int, call._args)) In the former case, everything is defined explicitly and it's clear that the function only accepts positional arguments. In the latter case, you're required to know the API of the library: that necessary objects are hidden behind the attributes call._func and call._args, and that the keyword arguments are silently discarded. It's an extremely leaky abstraction. You probably think that passing 'self' to every method is boilerplate too, and arguably it is. But the Python philosophy is "explicit is better than implicit".