python - 试图包装类方法,但 __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
解决方案
推荐阅读
- scala - Spark,如何将 AB,C 转换为 (A, List(B,C))
- r - 如何编写时间循环并给出一个数字
- python - 随机字典选择?
- c - 致命错误:curl/curl.h:没有使用 vcpkg 的文件或目录
- python - 将 PHP POST 请求中的值连接到要执行的 python 脚本中的变量
- java - 没有值的 Java 多键映射
- mysql - 按月选择sql
- php - 如何(通过 Blogger.com)生成一次性动态链接到我的电子书托管@DropBox?
- reactjs - 单击按钮后,如何使用 Reactjs 重定向到带有自动正文和发件人的 Outlook 邮件?
- r - 如何从文章中提取文本下方和上方的关键字