Reputation: 12575
Here is my python code. I have a class MyClass
with two static methods: my_method1
and my_method2
. Both methods are wrapped with a decorator called exception_handler
.
from functools import wraps
import sys
def exception_handler(function):
@wraps(function)
def decorator(self, *args, **kwargs):
try:
return function(self, *args, **kwargs)
except Exception, e:
print "EXCEPTION!: %s" % e
sys.exit(-1)
return decorator
class MyClass:
@staticmethod
@exception_handler
def my_method1(a, b, c,):
return "X"
@staticmethod
@exception_handler
def my_method2(e, f, g,):
print "Y"
return MyClass.my_method1(a=e, b=f, c=g)
print "Trying my_method1"
print MyClass.my_method1(1, 2, 3)
print ""
print "Trying my_method2"
print MyClass.my_method2(1, 2, 3)
When I run this code, I get the following:
Trying my_method1
X
Trying my_method2
Y
EXCEPTION!: decorator() takes at least 1 argument (0 given)
Why does the decorator fail in the second instance and how can I get around it?
It seems like the decorator fails when decorated method is a static method being called by another static method. But why this would happen makes no sense to me.
Upvotes: 2
Views: 865
Reputation: 1097
I think your code is failing without you noticing, can you try printing your a, b, c
*args ? You will find out that a
is self
!!! So it fails silently by assigning the wrong arguments.
Then why it raises an exception the second call here: MyClass.my_method1(a=e, b=f, c=g)
that's because your *args are empty now and self cannot replace any variable like before.
Upvotes: 0
Reputation: 4158
The problem is that staticmethods
do not take self as an argument. I am not sure why it works on the first two calls and not the third. However, removing self
from the decorator fixes it.
Here is the refactored code:
from functools import wraps
import sys
def exception_handler(function):
@wraps(function)
def decorator(*args, **kwargs):
try:
return function(*args, **kwargs)
except Exception as e:
print "EXCEPTION!: {}".format(e)
sys.exit(-1)
return decorator
class MyClass(object):
@staticmethod
@exception_handler
def my_method1(a, b, c, ):
return "X"
@staticmethod
@exception_handler
def my_method2(e, f, g, ):
print "Y"
return MyClass.my_method1(a=e, b=f, c=g)
print "Trying my_method1"
print MyClass.my_method1(1, 2, 3)
print
print "Trying my_method2"
print MyClass.my_method2(1, 2, 3)
Doing so gives these results:
Trying my_method1
X
Trying my_method2
Y
X
Upvotes: 1