1. 介绍
装饰器是程序开发中经常会用到的一个功能,用好了装饰器,开发效率如虎添翼,重要性相当于c语言中的指针。面试也经常问到。
2.手动实现
def set_func(func):
def call_func():
print("---这是权限验证1----")
print("---这是权限验证2----")
func()
return call_func
@set_func # 等价于demo1 = set_func(test1)
def demo1():
print("-----test1----")
# ret = set_func(demo1)
# ret() # 这里call_func()执行两遍,由于demo1,会调用@set_func
demo1()
3.装饰器应用
- 计算函数运行时间
import time
def set_func(func):
def call_func():
start_time = time.time()
func()
stop_time = time.time()
print('all times %f' % (stop_time - start_time))
return call_func
@set_func
def demo1():
print('----demo1----')
time.sleep(2)
demo1()
-
装饰器在@的时候就已经装饰
-
同一个装饰器可以对多个函数,有参和无参都可以装饰
-
对不定长参数和有返回值的函数进行装饰,即通用装饰器
def set_func(func):
print("---开始进行装饰")
def call_func(*args, **kwargs):
print("---这是权限验证1----")
print("---这是权限验证2----")
# func(args, kwargs) # 不行,相当于传递了2个参数 :1个元组,1个字典
return func(*args, **kwargs) # 拆包
return call_func
@set_func # 相当于 demo1 = set_func(demo1)
def demo1(num, *args, **kwargs):
print("-----demo1----%d" % num)
print("-----demo1----" , args)
print("-----demo1----" , kwargs)
return "ok"
@set_func
def demo2():
pass
ret = demo1(100, 200, 300, mm=100)
print(ret)
ret = demo2()
print(ret)
- 多个装饰器对同一个函数执行,装饰反向,执行正向
def set_func_1(func):
def call_func():
# "<h1>haha</h1>"
print('set_func_1')
return "<h1>" + func() + "</h1>"
return call_func
def set_func_2(func):
def call_func():
print('set_func_2')
return "<td>" + func() + "</td>"
return call_func
@set_func_1
@set_func_2
def get_str():
return "haha"
print(get_str())
# set_func_1
# set_func_2
# <h1><td>haha</td></h1>
- 使用类当做装饰器 (了解即可)
class Demo(object):
def __init__(self, func):
self.func = func
def __call__(self):
print("这里是装饰器添加的功能.....")
return self.func()
@Demo # 相当于get_str = Test(get_str)
def get_str():
return "haha"
print(get_str())
- 装饰器带参数 (解决如何设置权限等级)
from time import ctime, sleep
def timefun_arg(pre="hello"):
def time_fun(func):
def wrapped_func():
print("%s called at %s %s" % (func.__name__, ctime(), pre))
return func()
return wrapped_func
return time_fun
# 下面的装饰过程
# 1. 调用timefun_arg("itcast")
# 2. 将步骤1得到的返回值,即time_fun返回, 然后time_fun(foo)
# 3. 将time_fun(foo)的结果返回,即wrapped_func
# 4. 让foo = wrapped_fun,即foo现在指向wrapped_func
@timefun_arg("itcast")
def foo():
print("I am foo")
@timefun_arg("python")
def too():
print("I am too")
foo()
too()