首页 > 解决方案 > 试图包装类方法,但 __init__() 被包装了

问题描述

我试图了解装饰器,并试图为一个类编写一个装饰器,该类将包装类中的所有方法(内部方法除外)。我可以看到它正在尝试包装我想要包装的方法,但是当我尝试调用任何这些方法时,它似乎__init__()被包装了。

#!/usr/bin/python

import sys
import types
from functools import wraps

def classTracer(cls):
    for name,f in vars(cls).items():
        if isinstance(f, types.FunctionType) and not name.startswith('__'):
            print "I am wrapping method", name
            @wraps(f)
            def wrapper(*args, **kwargs):
                print "Entering %s()" % f.__name__
                rval = f(*args, **kwargs)
                print "Exited %s(), returning" % f.__name__, rval
                return rval
            setattr(cls, name, wrapper)
    return cls

@classTracer
class MyClass(object):
    def __init__(self):
        self.x = 1
    def foo(self, i):
        return i+7
    def bar(self, i):
        return i-7

def main():
    print 'create object'
    x = MyClass()
    print 'call bar'
    print x.bar(7)
    return 0

if __name__ == "__main__":
    sys.exit(main())

输出:

I am wrapping method bar
I am wrapping method foo
create object
call bar
Entering __init__()
Traceback (most recent call last):
  File "./test2.py", line 35, in <module>
    sys.exit(main())
  File "./test2.py", line 31, in main
    print x.bar(7)
  File "./test2.py", line 14, in wrapper
    rval = f(*args, **kwargs)
TypeError: __init__() takes exactly 1 argument (2 given)

我哪里错了?


编辑:感谢链接的问题,我能够修改我的包装器:

def classTracer(cls):
    def gen_wrapper(name, f):
        @wraps(f)
        def wrapper(*args, **kwargs):
            print "Entering %s()" % name
            rval = f(*args, **kwargs)
            print "Exited %s(), returning" % name, rval
            return rval
        return wrapper
    for name,f in vars(cls).items():
        if isinstance(f, types.FunctionType) and not name.startswith('__'):
            print "I am wrapping method", name
            setattr(cls, name, gen_wrapper(name, f))
    print 'loop done, last function was', name
    return cls

标签: pythonpython-decorators

解决方案


推荐阅读