Python装饰器与staticmethod一起使用。但是失败了2个静态方法。为什么?

时间:2015-11-16 05:39:59

标签: python static-methods python-decorators

这是我的python代码。我有一个MyClass课,有两个静态方法:my_method1my_method2。这两个方法都包含一个名为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)

当我运行此代码时,我得到以下内容:

Trying my_method1
X

Trying my_method2
Y
EXCEPTION!: decorator() takes at least 1 argument (0 given)

为什么装饰器在第二个实例中失败,我该如何绕过它?

当装饰方法是另一个静态方法调用的静态方法时,装饰器似乎失败了。但为什么会发生这种情况对我来说毫无意义。

2 个答案:

答案 0 :(得分:1)

问题是staticmethods不以自我为参数。我不确定为什么它适用于前两个调用而不是第三个调用。但是,从装饰器中删除self会修复它。

以下是重构代码:

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)

这样做可以得到以下结果:

Trying my_method1
X

Trying my_method2
Y
X

答案 1 :(得分:0)

我认为您的代码在没有注意到的情况下失败,您可以尝试打印a, b, c * args吗?你会发现aself!因此,它通过分配错误的参数而无声地失败。

那么为什么它会在第二次调用时引发异常:MyClass.my_method1(a=e, b=f, c=g)因为你的* args现在是空的而且self不能像以前那样替换任何变量。