06
0、 概念
什么叫装饰器,其实也可以叫做包装器。即对于一个既有的函数func(args),在调用它之前和之后,我们希望都做一些事情,把这个函数包装起来。
python中的装饰器分为两类:函数装饰器和类装饰器。
这里我们先讨论函数装饰器。
1. 不带参数的decorator
(1) 基本用法:
- def decorator1(func):
- def dec(*args):
- print 'pre action'
- result = func(*args)
- print 'post action'
- return result
- return dec
- @decorator1
- def test_f1(name):
- print name
- return None
- test_f1('name1') #out: preaction/name1/post action
- test_f1('name2') #out: preaction/name2/post action
(2) 这种现象的内部原理:
在python内部,当你做了这件事情:
- @decorator1
- def test_f1(name):
其实就是 test_f1 = decorator1(test_f1) #即test_f1作为参数传递给func。
此后的test_f1是装饰器中的dec函数对象了,而不是原来的函数的名称。当调用test_f1(‘name1’)的时候,其实调用的是dec(‘name1’)函数,而在dec函数内部,又调用了func,这样就造成了装饰器的效果。
这也解释了func是被装饰函数,*arg是被装饰函数的参数—这种现象了。
2. 带参数的decorator
(1) 基本用法:
- def wap(name):
- def decorator1(func):
- def dec(*args):
- print name
- print 'pre action'
- result = func(*args)
- print 'post action'
- return result
- return dec
- return decorator1
- @wap('f1')
- def test_f1(name):
- print name
- return None
- @wap('f2')
- def test_f2(name):
- print name
- return None
- test_f1('name1') #out: f1/pre action/name1/post action
- test_f1('name2') #out: f2/pre action/name2/post action
带参数的decorator,作用是通过传递参数可以定制不同的装饰器。
(2) 内部原理
这里和上面 不带参数的decorator类似,
- @wap('f1')
- def test_f1(name):
内部逻辑为: test_f1 = wap(‘f1’)(test_f1)
这里wap(‘f1’)返回是decorator1函数对象,这样的话,wap(‘f1’)(test_f1)其实就是decorator1(test_f1),这样就和上面的一样了。只不过这里传递了一个参数’f1’进入decorator内部,使得我们可以操作这个参数。
3. 函数decorator也可以修饰类成员函数
- class FOO:
- @decorator1
- def fun(self):
- print self.name
注意此时fun的self会被传递到decorator1中。此时把self看做普通的函数入参。
4. 函数decorator的叠加
(1) 用法
- def decorator1(func):
- def dec(*args):
- print 'd1 pre'
- result = func(*args)
- print 'd1 post'
- return result
- return dec
- def decorator2(func):
- def dec(*args):
- print 'd2 pre'
- result = func(*args)
- print 'd2 post'
- return result
- return dec
- @decorator1
- @decorator2
- def test(name):
- print name
- test('test') #out: d1 pre/d2 pre/test/d1 post/d2 post
(2) 原理
- @decorator1
- @decorator2
- def test(name):
- print name
和上面的类似,内部原理是:
test = decorator1(decorator2(test))
注意decorator1(decorator2(test)),不是说先执行decorator2(test),再执行decorator1。
而是先把decorator2(test)作为参数,最先执行decorator1,然后再执行decorator2.。
标签:f1,name,hawk189,def,用法,print,decorator,test,decorator1 From: https://blog.51cto.com/u_15858333/5855688