Merging python decorators with arguments into a single one
Clash Royale CLAN TAG#URR8PPP
up vote
9
down vote
favorite
I'm using two different decorators from two different libraries. Lets say: @decorator1(param1, param2)
and @decorator2(param3, param4)
. That I often use in many function as:
from moduleA import decorator1
from moduleB import decorator2
@decorator2(foo='param3', bar='param4')
@decorator1(name='param1', state='param2')
def myfunc(funcpar1, funcpar2):
...
Since it happens everytime, I would like to create a custom decorator that handle both of them. Something like:
@mycustomdecorator(name='param1', state='param2',
foo='param3', bar='param4')
def myfunc(funcpar1, funcpar2):
...
How to achieve that?
python python-decorators
 |Â
show 5 more comments
up vote
9
down vote
favorite
I'm using two different decorators from two different libraries. Lets say: @decorator1(param1, param2)
and @decorator2(param3, param4)
. That I often use in many function as:
from moduleA import decorator1
from moduleB import decorator2
@decorator2(foo='param3', bar='param4')
@decorator1(name='param1', state='param2')
def myfunc(funcpar1, funcpar2):
...
Since it happens everytime, I would like to create a custom decorator that handle both of them. Something like:
@mycustomdecorator(name='param1', state='param2',
foo='param3', bar='param4')
def myfunc(funcpar1, funcpar2):
...
How to achieve that?
python python-decorators
I don't think is the same, in post you mentioned the@customdecorator
is receiving decorators. It will not be this case.
– Lin
1 hour ago
You can easily extend this answer to add parameters though.
– Aran-Fey
1 hour ago
can you please instead mark as duplicated, add the extension, since I'm not being able achieve that from that answer.
– Lin
1 hour ago
I don't think we should have two separate Q&As for merging decorators with and without arguments, so I'm going to post a more complete answer in the other question.
– Aran-Fey
1 hour ago
1
Possible duplicate of Can I combine two decorators into a single one in Python?
– Julian Camilleri
1 hour ago
 |Â
show 5 more comments
up vote
9
down vote
favorite
up vote
9
down vote
favorite
I'm using two different decorators from two different libraries. Lets say: @decorator1(param1, param2)
and @decorator2(param3, param4)
. That I often use in many function as:
from moduleA import decorator1
from moduleB import decorator2
@decorator2(foo='param3', bar='param4')
@decorator1(name='param1', state='param2')
def myfunc(funcpar1, funcpar2):
...
Since it happens everytime, I would like to create a custom decorator that handle both of them. Something like:
@mycustomdecorator(name='param1', state='param2',
foo='param3', bar='param4')
def myfunc(funcpar1, funcpar2):
...
How to achieve that?
python python-decorators
I'm using two different decorators from two different libraries. Lets say: @decorator1(param1, param2)
and @decorator2(param3, param4)
. That I often use in many function as:
from moduleA import decorator1
from moduleB import decorator2
@decorator2(foo='param3', bar='param4')
@decorator1(name='param1', state='param2')
def myfunc(funcpar1, funcpar2):
...
Since it happens everytime, I would like to create a custom decorator that handle both of them. Something like:
@mycustomdecorator(name='param1', state='param2',
foo='param3', bar='param4')
def myfunc(funcpar1, funcpar2):
...
How to achieve that?
python python-decorators
python python-decorators
edited 55 mins ago
asked 1 hour ago
Lin
359112
359112
I don't think is the same, in post you mentioned the@customdecorator
is receiving decorators. It will not be this case.
– Lin
1 hour ago
You can easily extend this answer to add parameters though.
– Aran-Fey
1 hour ago
can you please instead mark as duplicated, add the extension, since I'm not being able achieve that from that answer.
– Lin
1 hour ago
I don't think we should have two separate Q&As for merging decorators with and without arguments, so I'm going to post a more complete answer in the other question.
– Aran-Fey
1 hour ago
1
Possible duplicate of Can I combine two decorators into a single one in Python?
– Julian Camilleri
1 hour ago
 |Â
show 5 more comments
I don't think is the same, in post you mentioned the@customdecorator
is receiving decorators. It will not be this case.
– Lin
1 hour ago
You can easily extend this answer to add parameters though.
– Aran-Fey
1 hour ago
can you please instead mark as duplicated, add the extension, since I'm not being able achieve that from that answer.
– Lin
1 hour ago
I don't think we should have two separate Q&As for merging decorators with and without arguments, so I'm going to post a more complete answer in the other question.
– Aran-Fey
1 hour ago
1
Possible duplicate of Can I combine two decorators into a single one in Python?
– Julian Camilleri
1 hour ago
I don't think is the same, in post you mentioned the
@customdecorator
is receiving decorators. It will not be this case.– Lin
1 hour ago
I don't think is the same, in post you mentioned the
@customdecorator
is receiving decorators. It will not be this case.– Lin
1 hour ago
You can easily extend this answer to add parameters though.
– Aran-Fey
1 hour ago
You can easily extend this answer to add parameters though.
– Aran-Fey
1 hour ago
can you please instead mark as duplicated, add the extension, since I'm not being able achieve that from that answer.
– Lin
1 hour ago
can you please instead mark as duplicated, add the extension, since I'm not being able achieve that from that answer.
– Lin
1 hour ago
I don't think we should have two separate Q&As for merging decorators with and without arguments, so I'm going to post a more complete answer in the other question.
– Aran-Fey
1 hour ago
I don't think we should have two separate Q&As for merging decorators with and without arguments, so I'm going to post a more complete answer in the other question.
– Aran-Fey
1 hour ago
1
1
Possible duplicate of Can I combine two decorators into a single one in Python?
– Julian Camilleri
1 hour ago
Possible duplicate of Can I combine two decorators into a single one in Python?
– Julian Camilleri
1 hour ago
 |Â
show 5 more comments
3 Answers
3
active
oldest
votes
up vote
6
down vote
accepted
I would argue that you shouldn't - using the original names for the decorators gives much better readability.
However, if you really want to, you can do it like this:
import functools
from moduleA import decorator1
from moduleB import decorator2
def my_decorator(foo, bar, name, state):
def inner(func):
@decorator2(foo=foo, bar=bar)
@decorator1(name=name, state=state)
@functools.wraps(func) # Not required, but generally considered good practice
def newfunc(*args, **kwargs)
return func(*args, **kwargs)
return newfunc
return inner
@my_decorator(foo='param3', bar='param4', name='param1', state='param2')
def myfunc(funcpar1, funcpar2):
...
It's simple really - just write a decorator that returns another decorator which will have it's inner function decorated with the other two decorators ;)
It might also be a good idea to use functools.wraps, for the sake of good habits. It's standard library and helps a lot with debugging and interactive console use: https://docs.python.org/3.7/library/functools.html
In general though, I'd say the one extra line of code is more than worth the clarity of using the decorators separately. You'll thank yourself when you read your own code in 3 more months.
1
You should be usingfunctools.wraps
though. If you tryprint(myfunc)
you'll get<function my_decorator.<locals>.inner.<locals>.newfunc at 0x7f5ee7bbee18>
as output.
– Aran-Fey
47 mins ago
You're right, of course. I was a bit in doubt because this question indicates a certain inexperience with decorators, and I wasn't sure whether to add it. I'll make an edit about it, since it's better to learn it right the first time around, though.
– Jacco van Dorp
45 mins ago
While I usually agree that saving a line or two is not worth a loss in readability, if I had to apply the same two decorators to more than a couple functions I'd certainly wonder whether it's accidental or not, and in the last case refactor the whole thing to avoid repetitions.
– bruno desthuilliers
44 mins ago
If they're from two different libraries, it's not accidental. @Aran-Fey: Whoops. That'll teach me from trying to edit to fast.
– Jacco van Dorp
41 mins ago
@Jacco but then I'd start wondering why I didn't ever see the authors of the libraries in the same room at the same time.
– Mad Physicist
37 mins ago
 |Â
show 1 more comment
up vote
2
down vote
This is just simple function composition, where decorator1
and decorator2
are returning the functions you want to compose. The real work can be abstracted out into a function compose
.
# In the special case of composing decorators, the lambda expression
# only needs to be defined with a single argument, like
#
# lambda func: f(g(func))
#
# but I show a more general form.
def compose(f, g):
return lambda *args, **kwargs: f(g(*args, **kwargs))
def customdecorator(foo, bar, name, state):
return compose(decorator2(foo=foo, bar=bar),
decorator1(name=name, state=state))
add a comment |Â
up vote
0
down vote
Decorator is nothing more than a syntax sugar to the syntax like func = decorator(func)
.
So, you can easily make your own decorator that does whatever you want with the following syntax:
def mycustomdecorator(foo, bar, name, state)
def innerdecorator(func):
func = decorator1(foo=foo, bar=bar)(func)
func = decorator2(name=name, state=state)(func)
def wrapper(*args, **kwargs):
func(*args, **kwargs)
return wrapper
return innerdecorator
After that, you should be able to use @mycustomdecorator with no hassle. Let me know if this works, I didn't test it but theoretically it should.
What's the magic there: first, we need to retrieve parameters for our decorators. This way, we are able to pass them on into nested function. Then, we are accepting our function as an argument, and the last, we are getting parameters for our function. We can nest our def-s as much as we need.
New contributor
Ôüøтрøù Úûøüõýúþ is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
That's not quite right. You have too many nested functions there.
– Aran-Fey
45 mins ago
Can you elaborate, please?
– Ã”üøтрøù Úûøüõýúþ
44 mins ago
1
If I have a functionfoo
that's decorated with@mycustomdecorator(...)
,foo
will be replaced bywrapper
, which returnsfoo
when it's called.
– Aran-Fey
42 mins ago
Yes, I believe this is the way to preserve arguments for both foo() and mycustomdecorator(). Am I wrong?
– Ã”üøтрøù Úûøüõýúþ
31 mins ago
1
(The wrong part is thatwrapper
should call, not return,func
.)
– chepner
18 mins ago
 |Â
show 7 more comments
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
6
down vote
accepted
I would argue that you shouldn't - using the original names for the decorators gives much better readability.
However, if you really want to, you can do it like this:
import functools
from moduleA import decorator1
from moduleB import decorator2
def my_decorator(foo, bar, name, state):
def inner(func):
@decorator2(foo=foo, bar=bar)
@decorator1(name=name, state=state)
@functools.wraps(func) # Not required, but generally considered good practice
def newfunc(*args, **kwargs)
return func(*args, **kwargs)
return newfunc
return inner
@my_decorator(foo='param3', bar='param4', name='param1', state='param2')
def myfunc(funcpar1, funcpar2):
...
It's simple really - just write a decorator that returns another decorator which will have it's inner function decorated with the other two decorators ;)
It might also be a good idea to use functools.wraps, for the sake of good habits. It's standard library and helps a lot with debugging and interactive console use: https://docs.python.org/3.7/library/functools.html
In general though, I'd say the one extra line of code is more than worth the clarity of using the decorators separately. You'll thank yourself when you read your own code in 3 more months.
1
You should be usingfunctools.wraps
though. If you tryprint(myfunc)
you'll get<function my_decorator.<locals>.inner.<locals>.newfunc at 0x7f5ee7bbee18>
as output.
– Aran-Fey
47 mins ago
You're right, of course. I was a bit in doubt because this question indicates a certain inexperience with decorators, and I wasn't sure whether to add it. I'll make an edit about it, since it's better to learn it right the first time around, though.
– Jacco van Dorp
45 mins ago
While I usually agree that saving a line or two is not worth a loss in readability, if I had to apply the same two decorators to more than a couple functions I'd certainly wonder whether it's accidental or not, and in the last case refactor the whole thing to avoid repetitions.
– bruno desthuilliers
44 mins ago
If they're from two different libraries, it's not accidental. @Aran-Fey: Whoops. That'll teach me from trying to edit to fast.
– Jacco van Dorp
41 mins ago
@Jacco but then I'd start wondering why I didn't ever see the authors of the libraries in the same room at the same time.
– Mad Physicist
37 mins ago
 |Â
show 1 more comment
up vote
6
down vote
accepted
I would argue that you shouldn't - using the original names for the decorators gives much better readability.
However, if you really want to, you can do it like this:
import functools
from moduleA import decorator1
from moduleB import decorator2
def my_decorator(foo, bar, name, state):
def inner(func):
@decorator2(foo=foo, bar=bar)
@decorator1(name=name, state=state)
@functools.wraps(func) # Not required, but generally considered good practice
def newfunc(*args, **kwargs)
return func(*args, **kwargs)
return newfunc
return inner
@my_decorator(foo='param3', bar='param4', name='param1', state='param2')
def myfunc(funcpar1, funcpar2):
...
It's simple really - just write a decorator that returns another decorator which will have it's inner function decorated with the other two decorators ;)
It might also be a good idea to use functools.wraps, for the sake of good habits. It's standard library and helps a lot with debugging and interactive console use: https://docs.python.org/3.7/library/functools.html
In general though, I'd say the one extra line of code is more than worth the clarity of using the decorators separately. You'll thank yourself when you read your own code in 3 more months.
1
You should be usingfunctools.wraps
though. If you tryprint(myfunc)
you'll get<function my_decorator.<locals>.inner.<locals>.newfunc at 0x7f5ee7bbee18>
as output.
– Aran-Fey
47 mins ago
You're right, of course. I was a bit in doubt because this question indicates a certain inexperience with decorators, and I wasn't sure whether to add it. I'll make an edit about it, since it's better to learn it right the first time around, though.
– Jacco van Dorp
45 mins ago
While I usually agree that saving a line or two is not worth a loss in readability, if I had to apply the same two decorators to more than a couple functions I'd certainly wonder whether it's accidental or not, and in the last case refactor the whole thing to avoid repetitions.
– bruno desthuilliers
44 mins ago
If they're from two different libraries, it's not accidental. @Aran-Fey: Whoops. That'll teach me from trying to edit to fast.
– Jacco van Dorp
41 mins ago
@Jacco but then I'd start wondering why I didn't ever see the authors of the libraries in the same room at the same time.
– Mad Physicist
37 mins ago
 |Â
show 1 more comment
up vote
6
down vote
accepted
up vote
6
down vote
accepted
I would argue that you shouldn't - using the original names for the decorators gives much better readability.
However, if you really want to, you can do it like this:
import functools
from moduleA import decorator1
from moduleB import decorator2
def my_decorator(foo, bar, name, state):
def inner(func):
@decorator2(foo=foo, bar=bar)
@decorator1(name=name, state=state)
@functools.wraps(func) # Not required, but generally considered good practice
def newfunc(*args, **kwargs)
return func(*args, **kwargs)
return newfunc
return inner
@my_decorator(foo='param3', bar='param4', name='param1', state='param2')
def myfunc(funcpar1, funcpar2):
...
It's simple really - just write a decorator that returns another decorator which will have it's inner function decorated with the other two decorators ;)
It might also be a good idea to use functools.wraps, for the sake of good habits. It's standard library and helps a lot with debugging and interactive console use: https://docs.python.org/3.7/library/functools.html
In general though, I'd say the one extra line of code is more than worth the clarity of using the decorators separately. You'll thank yourself when you read your own code in 3 more months.
I would argue that you shouldn't - using the original names for the decorators gives much better readability.
However, if you really want to, you can do it like this:
import functools
from moduleA import decorator1
from moduleB import decorator2
def my_decorator(foo, bar, name, state):
def inner(func):
@decorator2(foo=foo, bar=bar)
@decorator1(name=name, state=state)
@functools.wraps(func) # Not required, but generally considered good practice
def newfunc(*args, **kwargs)
return func(*args, **kwargs)
return newfunc
return inner
@my_decorator(foo='param3', bar='param4', name='param1', state='param2')
def myfunc(funcpar1, funcpar2):
...
It's simple really - just write a decorator that returns another decorator which will have it's inner function decorated with the other two decorators ;)
It might also be a good idea to use functools.wraps, for the sake of good habits. It's standard library and helps a lot with debugging and interactive console use: https://docs.python.org/3.7/library/functools.html
In general though, I'd say the one extra line of code is more than worth the clarity of using the decorators separately. You'll thank yourself when you read your own code in 3 more months.
edited 39 mins ago


Aran-Fey
20.1k53065
20.1k53065
answered 50 mins ago
Jacco van Dorp
2446
2446
1
You should be usingfunctools.wraps
though. If you tryprint(myfunc)
you'll get<function my_decorator.<locals>.inner.<locals>.newfunc at 0x7f5ee7bbee18>
as output.
– Aran-Fey
47 mins ago
You're right, of course. I was a bit in doubt because this question indicates a certain inexperience with decorators, and I wasn't sure whether to add it. I'll make an edit about it, since it's better to learn it right the first time around, though.
– Jacco van Dorp
45 mins ago
While I usually agree that saving a line or two is not worth a loss in readability, if I had to apply the same two decorators to more than a couple functions I'd certainly wonder whether it's accidental or not, and in the last case refactor the whole thing to avoid repetitions.
– bruno desthuilliers
44 mins ago
If they're from two different libraries, it's not accidental. @Aran-Fey: Whoops. That'll teach me from trying to edit to fast.
– Jacco van Dorp
41 mins ago
@Jacco but then I'd start wondering why I didn't ever see the authors of the libraries in the same room at the same time.
– Mad Physicist
37 mins ago
 |Â
show 1 more comment
1
You should be usingfunctools.wraps
though. If you tryprint(myfunc)
you'll get<function my_decorator.<locals>.inner.<locals>.newfunc at 0x7f5ee7bbee18>
as output.
– Aran-Fey
47 mins ago
You're right, of course. I was a bit in doubt because this question indicates a certain inexperience with decorators, and I wasn't sure whether to add it. I'll make an edit about it, since it's better to learn it right the first time around, though.
– Jacco van Dorp
45 mins ago
While I usually agree that saving a line or two is not worth a loss in readability, if I had to apply the same two decorators to more than a couple functions I'd certainly wonder whether it's accidental or not, and in the last case refactor the whole thing to avoid repetitions.
– bruno desthuilliers
44 mins ago
If they're from two different libraries, it's not accidental. @Aran-Fey: Whoops. That'll teach me from trying to edit to fast.
– Jacco van Dorp
41 mins ago
@Jacco but then I'd start wondering why I didn't ever see the authors of the libraries in the same room at the same time.
– Mad Physicist
37 mins ago
1
1
You should be using
functools.wraps
though. If you try print(myfunc)
you'll get <function my_decorator.<locals>.inner.<locals>.newfunc at 0x7f5ee7bbee18>
as output.– Aran-Fey
47 mins ago
You should be using
functools.wraps
though. If you try print(myfunc)
you'll get <function my_decorator.<locals>.inner.<locals>.newfunc at 0x7f5ee7bbee18>
as output.– Aran-Fey
47 mins ago
You're right, of course. I was a bit in doubt because this question indicates a certain inexperience with decorators, and I wasn't sure whether to add it. I'll make an edit about it, since it's better to learn it right the first time around, though.
– Jacco van Dorp
45 mins ago
You're right, of course. I was a bit in doubt because this question indicates a certain inexperience with decorators, and I wasn't sure whether to add it. I'll make an edit about it, since it's better to learn it right the first time around, though.
– Jacco van Dorp
45 mins ago
While I usually agree that saving a line or two is not worth a loss in readability, if I had to apply the same two decorators to more than a couple functions I'd certainly wonder whether it's accidental or not, and in the last case refactor the whole thing to avoid repetitions.
– bruno desthuilliers
44 mins ago
While I usually agree that saving a line or two is not worth a loss in readability, if I had to apply the same two decorators to more than a couple functions I'd certainly wonder whether it's accidental or not, and in the last case refactor the whole thing to avoid repetitions.
– bruno desthuilliers
44 mins ago
If they're from two different libraries, it's not accidental. @Aran-Fey: Whoops. That'll teach me from trying to edit to fast.
– Jacco van Dorp
41 mins ago
If they're from two different libraries, it's not accidental. @Aran-Fey: Whoops. That'll teach me from trying to edit to fast.
– Jacco van Dorp
41 mins ago
@Jacco but then I'd start wondering why I didn't ever see the authors of the libraries in the same room at the same time.
– Mad Physicist
37 mins ago
@Jacco but then I'd start wondering why I didn't ever see the authors of the libraries in the same room at the same time.
– Mad Physicist
37 mins ago
 |Â
show 1 more comment
up vote
2
down vote
This is just simple function composition, where decorator1
and decorator2
are returning the functions you want to compose. The real work can be abstracted out into a function compose
.
# In the special case of composing decorators, the lambda expression
# only needs to be defined with a single argument, like
#
# lambda func: f(g(func))
#
# but I show a more general form.
def compose(f, g):
return lambda *args, **kwargs: f(g(*args, **kwargs))
def customdecorator(foo, bar, name, state):
return compose(decorator2(foo=foo, bar=bar),
decorator1(name=name, state=state))
add a comment |Â
up vote
2
down vote
This is just simple function composition, where decorator1
and decorator2
are returning the functions you want to compose. The real work can be abstracted out into a function compose
.
# In the special case of composing decorators, the lambda expression
# only needs to be defined with a single argument, like
#
# lambda func: f(g(func))
#
# but I show a more general form.
def compose(f, g):
return lambda *args, **kwargs: f(g(*args, **kwargs))
def customdecorator(foo, bar, name, state):
return compose(decorator2(foo=foo, bar=bar),
decorator1(name=name, state=state))
add a comment |Â
up vote
2
down vote
up vote
2
down vote
This is just simple function composition, where decorator1
and decorator2
are returning the functions you want to compose. The real work can be abstracted out into a function compose
.
# In the special case of composing decorators, the lambda expression
# only needs to be defined with a single argument, like
#
# lambda func: f(g(func))
#
# but I show a more general form.
def compose(f, g):
return lambda *args, **kwargs: f(g(*args, **kwargs))
def customdecorator(foo, bar, name, state):
return compose(decorator2(foo=foo, bar=bar),
decorator1(name=name, state=state))
This is just simple function composition, where decorator1
and decorator2
are returning the functions you want to compose. The real work can be abstracted out into a function compose
.
# In the special case of composing decorators, the lambda expression
# only needs to be defined with a single argument, like
#
# lambda func: f(g(func))
#
# but I show a more general form.
def compose(f, g):
return lambda *args, **kwargs: f(g(*args, **kwargs))
def customdecorator(foo, bar, name, state):
return compose(decorator2(foo=foo, bar=bar),
decorator1(name=name, state=state))
edited 22 mins ago


Aran-Fey
20.1k53065
20.1k53065
answered 32 mins ago
chepner
230k27216313
230k27216313
add a comment |Â
add a comment |Â
up vote
0
down vote
Decorator is nothing more than a syntax sugar to the syntax like func = decorator(func)
.
So, you can easily make your own decorator that does whatever you want with the following syntax:
def mycustomdecorator(foo, bar, name, state)
def innerdecorator(func):
func = decorator1(foo=foo, bar=bar)(func)
func = decorator2(name=name, state=state)(func)
def wrapper(*args, **kwargs):
func(*args, **kwargs)
return wrapper
return innerdecorator
After that, you should be able to use @mycustomdecorator with no hassle. Let me know if this works, I didn't test it but theoretically it should.
What's the magic there: first, we need to retrieve parameters for our decorators. This way, we are able to pass them on into nested function. Then, we are accepting our function as an argument, and the last, we are getting parameters for our function. We can nest our def-s as much as we need.
New contributor
Ôüøтрøù Úûøüõýúþ is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
That's not quite right. You have too many nested functions there.
– Aran-Fey
45 mins ago
Can you elaborate, please?
– Ã”üøтрøù Úûøüõýúþ
44 mins ago
1
If I have a functionfoo
that's decorated with@mycustomdecorator(...)
,foo
will be replaced bywrapper
, which returnsfoo
when it's called.
– Aran-Fey
42 mins ago
Yes, I believe this is the way to preserve arguments for both foo() and mycustomdecorator(). Am I wrong?
– Ã”üøтрøù Úûøüõýúþ
31 mins ago
1
(The wrong part is thatwrapper
should call, not return,func
.)
– chepner
18 mins ago
 |Â
show 7 more comments
up vote
0
down vote
Decorator is nothing more than a syntax sugar to the syntax like func = decorator(func)
.
So, you can easily make your own decorator that does whatever you want with the following syntax:
def mycustomdecorator(foo, bar, name, state)
def innerdecorator(func):
func = decorator1(foo=foo, bar=bar)(func)
func = decorator2(name=name, state=state)(func)
def wrapper(*args, **kwargs):
func(*args, **kwargs)
return wrapper
return innerdecorator
After that, you should be able to use @mycustomdecorator with no hassle. Let me know if this works, I didn't test it but theoretically it should.
What's the magic there: first, we need to retrieve parameters for our decorators. This way, we are able to pass them on into nested function. Then, we are accepting our function as an argument, and the last, we are getting parameters for our function. We can nest our def-s as much as we need.
New contributor
Ôüøтрøù Úûøüõýúþ is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
That's not quite right. You have too many nested functions there.
– Aran-Fey
45 mins ago
Can you elaborate, please?
– Ã”üøтрøù Úûøüõýúþ
44 mins ago
1
If I have a functionfoo
that's decorated with@mycustomdecorator(...)
,foo
will be replaced bywrapper
, which returnsfoo
when it's called.
– Aran-Fey
42 mins ago
Yes, I believe this is the way to preserve arguments for both foo() and mycustomdecorator(). Am I wrong?
– Ã”üøтрøù Úûøüõýúþ
31 mins ago
1
(The wrong part is thatwrapper
should call, not return,func
.)
– chepner
18 mins ago
 |Â
show 7 more comments
up vote
0
down vote
up vote
0
down vote
Decorator is nothing more than a syntax sugar to the syntax like func = decorator(func)
.
So, you can easily make your own decorator that does whatever you want with the following syntax:
def mycustomdecorator(foo, bar, name, state)
def innerdecorator(func):
func = decorator1(foo=foo, bar=bar)(func)
func = decorator2(name=name, state=state)(func)
def wrapper(*args, **kwargs):
func(*args, **kwargs)
return wrapper
return innerdecorator
After that, you should be able to use @mycustomdecorator with no hassle. Let me know if this works, I didn't test it but theoretically it should.
What's the magic there: first, we need to retrieve parameters for our decorators. This way, we are able to pass them on into nested function. Then, we are accepting our function as an argument, and the last, we are getting parameters for our function. We can nest our def-s as much as we need.
New contributor
Ôüøтрøù Úûøüõýúþ is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
Decorator is nothing more than a syntax sugar to the syntax like func = decorator(func)
.
So, you can easily make your own decorator that does whatever you want with the following syntax:
def mycustomdecorator(foo, bar, name, state)
def innerdecorator(func):
func = decorator1(foo=foo, bar=bar)(func)
func = decorator2(name=name, state=state)(func)
def wrapper(*args, **kwargs):
func(*args, **kwargs)
return wrapper
return innerdecorator
After that, you should be able to use @mycustomdecorator with no hassle. Let me know if this works, I didn't test it but theoretically it should.
What's the magic there: first, we need to retrieve parameters for our decorators. This way, we are able to pass them on into nested function. Then, we are accepting our function as an argument, and the last, we are getting parameters for our function. We can nest our def-s as much as we need.
New contributor
Ôüøтрøù Úûøüõýúþ is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
edited 10 mins ago
New contributor
Ôüøтрøù Úûøüõýúþ is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
answered 49 mins ago


Ôüøтрøù Úûøüõýúþ
394
394
New contributor
Ôüøтрøù Úûøüõýúþ is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
Ôüøтрøù Úûøüõýúþ is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
Ôüøтрøù Úûøüõýúþ is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
That's not quite right. You have too many nested functions there.
– Aran-Fey
45 mins ago
Can you elaborate, please?
– Ã”üøтрøù Úûøüõýúþ
44 mins ago
1
If I have a functionfoo
that's decorated with@mycustomdecorator(...)
,foo
will be replaced bywrapper
, which returnsfoo
when it's called.
– Aran-Fey
42 mins ago
Yes, I believe this is the way to preserve arguments for both foo() and mycustomdecorator(). Am I wrong?
– Ã”üøтрøù Úûøüõýúþ
31 mins ago
1
(The wrong part is thatwrapper
should call, not return,func
.)
– chepner
18 mins ago
 |Â
show 7 more comments
That's not quite right. You have too many nested functions there.
– Aran-Fey
45 mins ago
Can you elaborate, please?
– Ã”üøтрøù Úûøüõýúþ
44 mins ago
1
If I have a functionfoo
that's decorated with@mycustomdecorator(...)
,foo
will be replaced bywrapper
, which returnsfoo
when it's called.
– Aran-Fey
42 mins ago
Yes, I believe this is the way to preserve arguments for both foo() and mycustomdecorator(). Am I wrong?
– Ã”üøтрøù Úûøüõýúþ
31 mins ago
1
(The wrong part is thatwrapper
should call, not return,func
.)
– chepner
18 mins ago
That's not quite right. You have too many nested functions there.
– Aran-Fey
45 mins ago
That's not quite right. You have too many nested functions there.
– Aran-Fey
45 mins ago
Can you elaborate, please?
– Ã”üøтрøù Úûøüõýúþ
44 mins ago
Can you elaborate, please?
– Ã”üøтрøù Úûøüõýúþ
44 mins ago
1
1
If I have a function
foo
that's decorated with @mycustomdecorator(...)
, foo
will be replaced by wrapper
, which returns foo
when it's called.– Aran-Fey
42 mins ago
If I have a function
foo
that's decorated with @mycustomdecorator(...)
, foo
will be replaced by wrapper
, which returns foo
when it's called.– Aran-Fey
42 mins ago
Yes, I believe this is the way to preserve arguments for both foo() and mycustomdecorator(). Am I wrong?
– Ã”üøтрøù Úûøüõýúþ
31 mins ago
Yes, I believe this is the way to preserve arguments for both foo() and mycustomdecorator(). Am I wrong?
– Ã”üøтрøù Úûøüõýúþ
31 mins ago
1
1
(The wrong part is that
wrapper
should call, not return, func
.)– chepner
18 mins ago
(The wrong part is that
wrapper
should call, not return, func
.)– chepner
18 mins ago
 |Â
show 7 more comments
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52517273%2fmerging-python-decorators-with-arguments-into-a-single-one%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
I don't think is the same, in post you mentioned the
@customdecorator
is receiving decorators. It will not be this case.– Lin
1 hour ago
You can easily extend this answer to add parameters though.
– Aran-Fey
1 hour ago
can you please instead mark as duplicated, add the extension, since I'm not being able achieve that from that answer.
– Lin
1 hour ago
I don't think we should have two separate Q&As for merging decorators with and without arguments, so I'm going to post a more complete answer in the other question.
– Aran-Fey
1 hour ago
1
Possible duplicate of Can I combine two decorators into a single one in Python?
– Julian Camilleri
1 hour ago