@decorator_with_params("Some string")
def my_function():
pass
you have to make 'decorator_with_params' a function that returns a decorator; i.e. def decorator_with_params(param):
def real_decorator(function):
def inner(*args, **kwargs):
print(param)
function(*args, **kwargs)
return inner
return real_decorator
(You can also do something similar with callable objects, but that's ickier IMO.)Demo of both (decorator as instance method and decorator with parameters): https://gist.github.com/jonathonw/dac88b715aca4e4f1b2f513e1f...
class MetaDec(args, here):
...
def __call__(self, func):
# Decorate function here
def meta_dec(args, here):
return MetaDec(args, here)
@meta_dec
def decorated:
...
(apologies for any syntax fails, python is not my best language)At which point one would imagine you can abstract out the __call__ part and just have a 'decorate' routine on any class designed to work what way or similar.
Whether this is an improvement or not over closures almost certainly depends on the use case, of course.
Given its reliance on '...' and the fact I'm not great at python and typed it straight into the comment ... no. No it doesn't.
> Wouldn't you need to create a instance within meta_dec and return the result of the __call__ method.
No, like with ES6 parameterised decorators return a function that then gets called with the thing being decorated.
> See at first glance I won't think it would work if I didn't know __call__ is a magic method in python.
(1) my reply was assuming the context of us both having just read the article, which has an example with __call__
(2) as I said in my original comment, you would abstract this away (and document it), I was sketching out an alternative implementation path to allow you to have an object instead of a closure since you didn't seem to be happy with closures, not offering a complete solution
> Mixing classes and FP like that doesn't resonate well with me tbh, but yeah you could do it ... but should you?
(3) if you don't like closures and you don't like objects, I'm not sure what other combined function+data abstraction is available in python that you wouldn't also dislike
(4) I'd probably consider doing it if I had a bunch of similar decorators and found the functional approach was starting to groan at the seams - I use objects for 'parameterised bag of functions, possibly with inheritance' quite a lot for that purpose
> It can be a real pain to read code like this if it's overdone
wherein (4) is, when things start getting complicated, a way to end up avoiding things turning into closure soup. Also being able to selectively override things with inheritance can really help factor things out and clean things up.
> at some point it doesn't seem like overkill anymore.
Though I suspect "at that point, ask yourself if you're overengineering it and only if you're sure you aren't consider moving to a class" definitely applies :)
class FancyDecorator():
__init__(self, *args):
self.args = args
__call__(self, fn):
return decorate_fn_with_args(fn, self.args)
dec = FancyDecorator(42)
@dec
def foo():
pass
@FancyDecorator(41)
def bar()
pass
Might have it wrong since I haven't messed with decorators in a while and they aren't exactly what one would call simple.--edit--
code formatting is all wonky so...