无参数的函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 from time import ctime, sleep def timefun(func): def wrappedfunc(): print "%s called at %s" % (func.__name__, ctime()) func() return wrappedfunc @timefun def foo(): print "I am foo" foo() sleep(2) foo()
运行结果
1 2 3 4 foo called at Fri Aug 4 17:48:31 2017 I am foo foo called at Fri Aug 4 17:48:33 2017 I am foo
被装饰的函数有参数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 from time import ctime, sleep def timefun(func): def wrappedfunc(a, b): print "%s called at %s" % (func.__name__, ctime()) print a, b func(a, b) return wrappedfunc @timefun def foo(a, b): print a + b foo(3, 5) sleep(2) foo(2, 4)
运行
1 2 3 4 5 6 foo called at Fri Aug 4 17:36:22 2017 3 5 8 foo called at Fri Aug 4 17:36:24 2017 2 4 6
被装饰的函数有不定长参数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 from time import ctime, sleep def timefun(func): def wrappedfunc(*args, **kwargs): print "%s called at %s" %(func.__name__,ctime()) func(*args, **kwargs) return wrappedfunc @timefun def foo(a, b, c): print (a + b + c) foo(3, 5, 7) sleep(2) foo(2, 4, 9)
运行结果
1 2 3 4 foo called at Fri Aug 4 17:52:17 2017 15 foo called at Fri Aug 4 17:52:19 2017 15
装饰器中的return 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 from time import ctime, sleep def timefun(func): def wrappedfunc(): print "%s called at %s" % (func.__name__, ctime()) func() return wrappedfunc @timefun def foo(): print "I am foo" @timefun def getInfo(): return '-----haha-----' foo() sleep(2) foo() print (getInfo())
运行结果
1 2 3 4 5 6 foo called at Fri Aug 4 17:57:07 2017 I am foo foo called at Fri Aug 4 17:57:09 2017 I am foo getInfo called at Fri Aug 4 17:57:09 2017 None
修改装饰器为return func() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 from time import ctime, sleep def timefun(func): def wrappedfunc(): print "%s called at %s" % (func.__name__, ctime()) return func() return wrappedfunc @timefun def foo(): print "I am foo" @timefun def getInfo(): return "-----haha-----" foo() sleep(2) foo() print (getInfo())
运行结果
1 2 3 4 5 6 foo called at Fri Aug 4 18:05:04 2017 I am foo foo called at Fri Aug 4 18:05:06 2017 I am foo getInfo called at Fri Aug 4 18:05:06 2017 -----haha-----
总结
1 一般情况下为了让装饰器更通用,可以有return
装饰器带参数,在原有装饰器的基础上,设置外部变量 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 from time import ctime, sleep def timefun_arg(pre="hello" ): def timefun(func): def wrappedfunc(): print "%s called at %s %s" % (func.__name__, ctime(), pre) return func() return wrappedfunc return timefun @timefun_arg("matrix" ) def foo(): print "I am foo" @timefun_arg("python" ) def too(): print "I am too" foo() sleep(2) foo() too() sleep(2) too()
运行结果
1 2 3 4 5 6 7 8 foo called at Fri Aug 4 18:11:43 2017 matrix I am foo foo called at Fri Aug 4 18:11:45 2017 matrix I am foo too called at Fri Aug 4 18:11:45 2017 python I am too too called at Fri Aug 4 18:11:47 2017 python I am too
类装饰器(拓展) 装饰器函数其实是这样一个接口约束,它必须接受一个callable对象作为参数,然后返回一个callable对象。在Python中一般callable对象都是函数,但也有例外。只要某个对象重写了 call () 方法,那么这个对象就是callable的
1 2 3 4 5 6 7 8 class Test(): def __call__(self): print ('call me!' ) t = Test() t()
运行结果