装饰器
装饰器的定义域普通函数的定义在形式上完全一致,只不过装饰器函数的参数必须要有函数或类对象,然后在装饰器函数中重新定义一个新的函数或类,并在其中执行某些功能前后或中间来使用被装饰的函数或类,最后返回这个新定义的函数或类,以下是一个简单的装饰器函数的定义代码:
def demo_decorater(fun): # 定义装饰器函数(参数为fun,可接收函数的对象)
def inner(*args,**kwargs): # 新定义一个包装器函数用于返回
pass # 要添加的功能
fun(**args,**kwargs) # 包装器函数中调用被装饰的函数
pass
return inner # 返回包装器函数
@demo_decorater # 语法糖,表示下面这个函数有装饰器
def decorated():
pass
多个装饰器
装饰函数
用装饰器装饰函数,首先要定义装饰器,然后用定义的装饰器来装饰函数
【实例】
def outer(fun): # 定义一个装饰器outer
def wrapper(*args,**kwargs): # 定义包装器函数
print('开始运行------')
fun(*args,**kwargs) # 调用被装饰函数
print('运行结束------')
return wrapper # 返回包装器函数
@outer
def demo_decoration(x):
a = []
for i in range(x):
a.append(x)
print(a)
@outer # 装饰器语法糖
def hello(name):
print('Hello',name)
if _ _name_ _=='_ _main_ _':
demo_decoration(5)
print()
hello('John')
【运行结果】
开始运行------
[0,1,2,3,4]
运行结束------
开始运行------
Hello John
运行结束------
带参数的装饰器
装饰器也可以参数的,比如’@outer(‘callcall’)’,可将前面的实例中的装饰器改成带参数的装饰器:
def outer(action):
def demo_decorater(fun): # 定义装饰器函数(参数为fun,可接收函数的对象)
def wrapper(*args,**kwargs): # 新定义一个包装器函数用于返回
pass # 要添加的功能
fun(**args,**kwargs) # 包装器函数中调用被装饰的函数
pass
return wrapper
return demo_decorater
装饰器函数中嵌套了两层的函数,一层层向外返回函数,最外层的参数并不是可调用类型的对象
实例:
import time
import functools
#print time.ctime()
def log(kind):
def add_log(fun):
@functools.wraps(fun)
def wrapper(*args,**kwargs):
start_time = time.time()
res = fun(*args,**kwargs)
end_time = time.time()
print '<%s> [%s] 函数名:%s,运行时间:%.5f,运行返回值结果:%d' %(kind,time.ctime(),fun.__name__,end_time-start_time,res)
return res
return wrapper
return add_log
@log('westos')
# log('dubug) --> 返回值是add_log
# add = add_log(add)
def add(x,y):
time.sleep(1)
return x+y
# wrapper(1,2)
print add(1,2)