python 装饰器详解
2017-09-14 16:59
232 查看
1. 最简单的装饰器
def decorator(fun): print 'decorator befor warpper' def wrapper(): print 'wrapper begin' fun() print 'wrapper end' return wrapper @decorator def decorated_do_something(): print 'decorated do something' print decorated_do_something print '*******************' print decorated_do_something()
运行结果:
decorator befor warpper <function wrapper at 0x0000000002BEE828> ******************* wrapper begin decorated do something wrapper end None
所以:
1. decorated_do_something相当于decorator(decorated_do_something),所以返回是wrapper 方法。
2. decorated_do_something()相当于decorator(decorated_do_something)(), 即wrapper()
测试查看decorated_do_something的函数名:
def decorator(fun): print 'decorator befor warpper' def wrapper(): print 'wrapper begin' fun() print 'wrapper end' return wrapper @decorator def decorated_do_something(): print 'decorated do something' print decorated_do_something.__name__
运行结果如下:
decorator befor warpper wrapper
2. 目标函数带固定参数的装饰器
def decorator(fun): print 'decorator befor warpper' def wrapper(arg): print 'wrapper begin' print 'arg: '+arg fun(arg) print 'wrapper end' return wrapper @decorator def decorated_do_something(arg): print 'decorated do something' print 'arg: '+arg def do_something(arg): print 'do something' print 'arg: '+arg decorated_do_something('decorated arg')
运行结果如下:
decorator befor warpper wrapper begin
arg: decorated arg
decorated do something
arg: decorated arg
wrapper end
decorated_do_something(‘decorated arg’)相当于decorator(decorated_do_something)(‘decorated arg’)
3. 目标函数带不固定参数的装饰器
ddef decorator(fun): print 'decorator befor warpper' def wrapper(*args, **kwargs): print 'wrapper begin' print 'args: '+ str(args)+"; kwargs: "+ str(kwargs) fun(*args, **kwargs) print 'wrapper end' return wrapper @decorator def decorated_do_something1(arg): print 'decorated do something' print 'arg: '+arg print 'decorated_do_something1 end' @decorator def decorated_do_something2(*args, **kwargs): print 'do something' print 'args: '+ str(args)+"; kwargs: "+ str(kwargs) print 'decorated_do_something2 end' decorated_do_something1('only one arg') print '***************' decorated_do_something2('arg1','arg2', arg3='arg3',arg4='arg4')
运行结果如下:
decorator befor warpper
decorator befor warpper wrapper begin
args: ('only one arg',); kwargs: {}
decorated do something
arg: only one arg
decorated_do_something1 end
wrapper end
***************
wrapper begin
args: ('arg1', 'arg2'); kwargs: {'arg3': 'arg3', 'arg4': 'arg4'}
do something
args: ('arg1', 'arg2'); kwargs: {'arg3': 'arg3', 'arg4': 'arg4'}
decorated_do_something2 end
wrapper end
4. 带参数的装饰器
def decorator(arg): print 'decorator before _decorator, decorator arg: '+arg def _decorator(fun): print 'decorator befor warpper' def wrapper(*args, **kwargs): print 'wrapper begin' print 'args: '+ str(args)+"; kwargs: "+ str(kwargs) fun(*args, **kwargs) print 'wrapper end' return wrapper return _decorator @decorator('2') def decorated_do_something(arg): print 'decorated do something started' print 'arg: '+arg print 'decorated_do_something end' print decorated_do_something.__name__ decorated_do_something("decorated_do_something's arg")
运行结果如下:
decorator before _decorator, decorator arg: 2
decorator befor warpper wrapper
wrapper begin
args: ("decorated_do_something's arg",); kwargs: {}
decorated do something started
arg: decorated_do_something's arg
decorated_do_something end
wrapper end
5. 被装饰器装饰过的函数的函数名
def decorator(fun): def wrapper(*args, **kwargs): fun(*args, **kwargs) return wrapper @decorator def decorated_do_something(): print 'decorated do something started' print decorated_do_something.__name__
运行结果:
wrapper
可以看出, decorated_do_something的函数名变成了wrapper,这不是我们想要的。 python的unctools.wraps提供了解决方法
import functools def decorator(fun): @functools.wraps(fun) def wrapper(*args, **kwargs): fun(*args, **kwargs) return wrapper @decorator def decorated_do_something(): print 'decorated do something started' print decorated_do_something.__name__
运行结果:
decorated_do_something
6. 装饰器类
需求:让函数只能运行指定次数class decorator(): def __init__(self, max): self.max=max self.count=0 def __call__(self,fun): self.fun=fun return self.call_fun def call_fun(self, *args, **kw): self.count +=1 if(self.count>self.max): print "%s run more than %d times" %(self.fun.__name__, self.max) else: self.fun(*args, **kw) @decorator(2) def decorated_do_something(): print 'decorated_do_something running' @decorator(3) def decorated_do_something1(): print 'decorated_do_something1 running' for i in xrange(4): decorated_do_something() decorated_do_something1()
运行结果:
decorated_do_something running decorated_do_something1 running decorated_do_something running decorated_do_something1 running decorated_do_something run more than 2 times decorated_do_something1 running decorated_do_something run more than 2 times decorated_do_something1 run more than 3 times
decorated_do_something相当于 decorator.init(args)(fun)
相关文章推荐
- (进阶)详解 Python 的装饰器
- 详解 Python中LEGB和闭包及装饰器
- Python中的装饰器用法详解
- python基础 之 装饰器详解
- python之装饰器详解
- python中装饰器详解
- python 闭包和装饰器详解
- Python中装饰器兼容加括号和不加括号的写法详解
- 详解python中闭包和装饰器
- Python中的各种装饰器详解
- 详解python中的装饰器
- 【转】详解Python的装饰器
- python中函数总结之装饰器闭包详解
- Python中的装饰器及@用法详解
- 详解Python的装饰器
- Python 装饰器详解
- Python中的装饰器用法详解
- Python 装饰器详解
- Python 简单装饰器白话文详解
- 详解Python的装饰器--一步一步理解装饰器