python基础语法(13)
装饰器
装饰去常被用于有切面需求的场景,较为经典的应用有:日志插入,增加计时逻辑来检测性能,加入事务处理等。
装饰器可以抽离出大量函数中与函数本身无关的雷同代码并继续使用。
概括的讲:
装饰器的作用就是为已经存在的对象添加额外的功能
装饰器中返回的函数是参数列表与调用装饰器完全一致的函数。
def timeit(func):
# 定义一个内嵌的包装函数,给传入的函数加上计时功能的包装
def wrapper():
start = time.clock()
func()
end =time.clock()
print 'used:', end - start
# 将包装后的函数返回
return wrapper
foo = timeit(foo) #传入的参数foo为原函数名,变量foo为新变量不是原函数
foo()
引入装饰器后可以将代码写成如下样子:
import time
def timeit(func):
def wrapper():
start = time.clock()
func()
end =time.clock()
print 'used:', end - start
return wrapper
@timeit
def foo():
print 'in foo()'
foo()
重点关注第11行的@timeit,在定义上加上这一行与另外写foo = timeit(foo)完全等价,千万不要以为@有另外的魔力。除了字符输入少了一些,还有一个额外的好处:这样看上去更有装饰器的感觉。
对带参数的函数使用装饰器
内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象
import datetime,time
def out(func):
def inner(*args):
start = datetime.datetime.now()
func(*args)
end = datetime.datetime.now()
print(end-start)
print("out and inner")
return inner
@out
def myfunc(*args):
time.sleep(1)
print("args is{}".format(args))
myfunc("lalalal")
个人理解,为什么装饰器中return inner就可以调用inner(),因为@ 的机制为:
@out
def my func()
等同于func = out(func)
此时func = inner
当调用func()时
相当于调用inner()
给装饰器参数
#coding:utf-8
def outermost(*args):
def out(func):
print ("装饰器参数{}".format(args))
def inner(*args):
print("innet start")
func(*args)
print ("inner end")
return inner
return out
@outermost(666)
def myfun(*args):
print ("试试装饰器和函数都带参数的情况,被装饰的函数参数{}".format(args))
myfun("zhangkun")
分析:
带参数的装饰器中,装饰器参数会多一层函数包裹,最外层的包裹用来获取装饰器传递的参数,里面一层包裹用来获取带有装饰器的函数传的参数。
网友评论