这部分我参考了廖雪峰老师的网站内容:装饰器
这里补充下自己的看法:
先来一个例子
def begin(f):
print f.__name__
return f
@begin
def now():
print '2016-02-21
结果显示(这里还没有调用now()函数):
now
如果调用now()函数,那么则会有
2016-02-21
这是为什么呢?按我的理解,如果使用装饰器,实际上就是使用函数式编程.在这里,Python解释器将这样解释:
now=begin(now)
在这里,将now作为函数参数传入begin()函数中,在begin()函数中,先执行print语句,然后返回函数f,这里的f其实就是now().返回now函数,又”赋值”给now,实际就是让now再指向now()函数地址.这时,再调用now(),就会执行原来now()函数中的内容,即:print ‘2016-02-21’.
这里用装饰器来定义这种功能,我想是非常恰当的.因为这个功能只是给函数”装饰”一些功能,而且这些功能并不是当前这个被装饰函数必须的或者这个函数所独有的.
那如果我想同时做到打印
**now
2016-02-21**
可以这样做:
def begin(f):
def wrapper(*args,**kw):
print f.__name__
return f(*args,**kw)
return wrapper
@begin
def now():
print '2016-02-21
这时再调用now(),就会出现我们想要的结果了.
来分析一下,使用装饰器,实际执行过程依然是:now=begin(now),这样现在now实际指向的就是wrapper函数,调用now.name,我们就会发现有:
那么这是再调用now(),实际上执行的就是wrapper()函数.那么在wrapper()函数就会执行print语句,并调用函数打印print 2016-02-21
最后,实现廖老师在小结中提到的一个要求.编写一个函数的函数装饰器,可以在函数调用前后打印”begin call+函数名字”和”after call+函数名字”.
def begin(func):
def decorator(g):
def wrapper(*args,**kw):
print 'begin call %s().' % func.__name__
func()
return g(*args,**kw)
return wrapper
return decorator
def now():
print '2016-02-21'
@begin(now)
def after(g):
print 'after call %s().' % g.__name__
结果如图:
这里分析一下.因为要做到函数调用前后打印”begin call+函数名字”和”after call+函数名字”.所以,我的设想是先在装饰器中打印begin call+函数名字,并完成函数调用.接下来,在被装饰函数中打印after call+函数名字.
对于装饰器:
def begin(func):
def decorator(g):
def wrapper(*args,**kw):
print 'begin call %s().' % func.__name__
func()
return g(*args,**kw)
return wrapper
return decorator
函数begin接受一个函数func作为参数,这个func就是我们要打印名字的函数.然后,decorator函数同样也是接受一个函数g作为参数,这个函数g就是被装饰函数.接下来,在wrapper函数中,先打印”beging call+函数名字”,接着调用我们的函数func().剩下就是常规的装饰器代码了.
对于我们被装饰的函数:
@begin(now)
def after(g):
print 'after call %s().' % g.__name__
实际上,它只是接受一个函数g作为参数,打印这个函数的名字.
于是,这样就可以完成我们上面的任务了.
总的来说,目前自己对装饰器也是初步了解,有待于进一步使用.