带有包装类方法参数的decorator问题

时间:2014-08-15 02:48:57

标签: python decorator class-method python-decorators

我正在尝试编写一个带有参数的装饰器,这些参数包装了特定类的方法。我已经尝试了函数和类装饰器并遇到了不同的错误。玩弄签名的参数并没有帮助。

使用示例

class X(object):
    def __init__():
        self.a = True
        self.b = ""

    @my_deco([])
    def xfunc(self, x, y):
        do stuff...

foo = X()
foo.xfunc()

功能装饰器:

def my_deco(param1):
    def wrapped(func):
        def wrapped_f(self, *args, **kwargs):
            try:
                self.a = True
                return func(self, *args, **kwargs)
            except Exception as e:
                self.b = str(e)
                self.a = False
                return param1
        return wrapped_f
    return wrapped

给出了这个错误:TypeError:wrapped()只取1个参数(给定3个)

班级装饰者:

class my_deco(object):

    def __init__(self, param1=False):
        self.param1 = param1

    def __call__(self, f):

        @wraps(f)
        def wrapped_f(self, *args, **kwargs):
            try:
                self.a = True
                return f(self, *args, **kwargs)
            except Exception as e:
                self.b = str(e)
                self.a = False
                return self.param1
        return wrapped_f
    #
    #def __get__(self, obj, objtype):
    #    """Support instance methods."""
    #    import functools
    #    return functools.partial(self.__call__, obj)

给出了这个错误:TypeError:调用()只需要2个参数(给定3个)

有关如何使其发挥作用的任何线索?

1 个答案:

答案 0 :(得分:1)

在尝试创建可运行代码以发布为例时,我遇到了我的错误。在编写包装器的某些时候可能会混淆并尝试让它工作,我忽略了一个简单的错误。

以下是工作示例。我犯的错误是我没有将参数传递给我正在测试的方法的装饰器,从而导致异常。这解释了问题,因为装饰器需要一个参数。

def my_deco(param1):
    def wrapped(func):
        def wrapped_f(self, *args, **kwargs):
            try:
                self.a = True
                return func(self, *args, **kwargs)
            except Exception as e:
                self.b = str(e)
                self.a = False
                return param1
        return wrapped_f
    return wrapped

class Base(object):
    def __init__(self, attr1, attr2):
        self.attr1 = attr1
        self.attr2 = attr2
        self.a = False
        self.b = ""

    @my_deco([])
    def xfunc(self, x, y):
        return x + y

def ClassFactory(attr1, attr2, base=Base):
    class NewClass(Base):
        def __init__(self):
            super(NewClass, self).__init__(attr1, attr2)

    return NewClass

ChildClass = ClassFactory("foo", "bar")
child = ChildClass()

print child.xfunc(1, 2) # no exception
print child.xfunc('x', 2) # throws exception