I have a function my cause exception and i want it to be a decorator. The code is as follow:
def des(i):
def new_func(func):
if i == 1:
raise Exception
else:
return func
return new_func
@des(1)
def func():
print "!!"
if __name__ == '__main__':
try:
func()
except Exception:
print 'error'
but the output is:
Traceback (most recent call last):
File "D:/des.py", line 10, in <module>
@des(1)
File "D:/des.py", line 4, in new_func
raise Exception
Exception
so, how can I catch this exception?
As the other answers have explained, your current issue is that you're getting the exception raised when the decorator is applied to the function, not when the function is called.
To fix this, you need to make the decorator return a function that does the exception raising. Here's how that could work:
import functools
def des(i):
def decorator(func):
if i != 1:
return func # no wrapper needed
@functools.wraps(func)
def raiser(*args, **kwargs):
raise Exception
return raiser
return decorator
The des
function is a "decorator factory". It doesn't really doesn't do anything other than providing a scope to hold the i
parameter for the decorator that it returns.
The decorator
function does the check to see if anything special needs to be done. If not, it returns the decorated function unmodified. If i==1
, it returns a custom function.
The raiser
function is the decorator's return value if i==1
. It always raises an exception when it is called. The functools.wraps
decorator applied to it is not strictly necessary, but it makes it look more like the original function (same __name__
, __doc__
, etc).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With