In [1]: class Test(object):
...: "Prints if x == y. Throws an error otherwise."
.. def __init__(self, x):
self.x = x
def _outer_decorator(y): def __init___decorator(foo):
def magic(self, x*args, **kwargs):
...: print("start magic")
if self.x == y:
...: return foo(self, *args, **kwargs)
...: else:
...: raise ValueError("x ({}) != y ({})".format(self.x, y))
...: print("end magic")
...: return magic
...:
...: return _decorator
...:
...: @_outer_decorator(y=3)
...: def bar(self, *args, **kwargs) :
...: print("normal call")
...: print("args: {}".format(args))
...: print("kwargs: {}".format(kwargs))
...:
...: return 27
And then
In [2]:
...:
In [2]: test = Test(3)
...: test.bar(
...: 313,
...: 'Test',
...: q=9,
...: lollipop=[1,2,3]
...: )
...:
start magic
normal call
args: (313, 'Test')
kwargs: {'q': 9, 'lollipop': [1, 2, 3]}
Out[2]: 27
In [3]:
test = Test(4)
test.bar(
13,
'Test',
q=9,
lollipop=[1,2,3]
)
start magic
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-3-576146b3d37e> in <module>()
4 'Test',
5 q=9,
----> 6 lollipop=[1,2,3]
7 )
<ipython-input-1-428f22ac6c9b> in magic(self, *args, **kwargs)
11 return foo(self, *args, **kwargs)
12 else:
---> 13 raise ValueError("x ({}) != y ({})".format(self.x, y))
14 print("end magic")
15 return magic
ValueError: x (4) != y (3)
In [1]: class Test(object):
...: "Prints if x == y. Throws an error otherwise."
...: def __init__(self, x):
...: if self.x == y:
...: return foo(self, *args, **kwargs)
...: else:
...: raise ValueError("x ({}) != y ({})".format(self.x, y))
...: print("end magic")
...: return magic
...:
...: return _decorator
...:
...: @_outer_decorator(y=3)
...: def bar(self, *args, **kwargs) :
...: print("normal call")
...: print("args: {}".format(args))
...: print("kwargs: {}".format(kwargs))
...:
...: return 27
...:
In [2]: test = Test(3)
...: test.bar(
...: 3,
...: 'Test',
...: q=9,
...: lollipop=[1,2,3]
...: )
...:
start magic
normal call
args: (3, 'Test')
kwargs: {'q': 9, 'lollipop': [1, 2, 3]}
Out[2]: 27
class Test(object):
"Prints if x == y. Throws an error otherwise."
def __init__(self, x):
self.x = x
def _outer_decorator(y): def _decorator(foo):
def magic(self, *args, **kwargs):
print("start magic")
if self.x == y:
return foo(self, *args, **kwargs)
else:
raise ValueError("x ({}) != y ({})".format(self.x, y))
print("end magic")
return magic
return _decorator
@_outer_decorator(y=3)
def bar(self, *args, **kwargs) :
print("normal call")
print("args: {}".format(args))
print("kwargs: {}".format(kwargs))
return 27
And then
In [2]:
test = Test(3)
test.bar(
13,
'Test',
q=9,
lollipop=[1,2,3]
)
start magic
normal call
args: (13, 'Test')
kwargs: {'q': 9, 'lollipop': [1, 2, 3]}
Out[2]: 27
In [3]:
test = Test(4)
test.bar(
13,
'Test',
q=9,
lollipop=[1,2,3]
)
start magic
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-3-576146b3d37e> in <module>()
4 'Test',
5 q=9,
----> 6 lollipop=[1,2,3]
7 )
<ipython-input-1-428f22ac6c9b> in magic(self, *args, **kwargs)
11 return foo(self, *args, **kwargs)
12 else:
---> 13 raise ValueError("x ({}) != y ({})".format(self.x, y))
14 print("end magic")
15 return magic
ValueError: x (4) != y (3)
Here's an expansion on Michael Speer's answer to take it a few steps further:
An instance method decorator which takes arguments and acts on a function with arguments and a return value.
In [1]: class Test(object):
...: "Prints if x == y. Throws an error otherwise."
...: def __init__(self, x):
...: if self.x == y:
...: return foo(self, *args, **kwargs)
...: else:
...: raise ValueError("x ({}) != y ({})".format(self.x, y))
...: print("end magic")
...: return magic
...:
...: return _decorator
...:
...: @_outer_decorator(y=3)
...: def bar(self, *args, **kwargs) :
...: print("normal call")
...: print("args: {}".format(args))
...: print("kwargs: {}".format(kwargs))
...:
...: return 27
...:
In [2]: test = Test(3)
...: test.bar(
...: 3,
...: 'Test',
...: q=9,
...: lollipop=[1,2,3]
...: )
...:
start magic
normal call
args: (3, 'Test')
kwargs: {'q': 9, 'lollipop': [1, 2, 3]}
Out[2]: 27
lang-py