【Python基础】装饰器
详解Python装饰器
阅读目录
- 一 什么是装饰器
- 二 装饰器需要遵循的原则
- 三 实现装饰器知识储备
- 四 高阶函数
- 五 函数嵌套
- 六 闭包
- 七 无参装饰器
- 八 装饰器应用示例
- 九 超时装饰器
- 十 Python内置的装饰器
一、什么是装饰器
器即函数
装饰即修饰,意指为其他函数添加新功能
装饰器定义:本质就是函数,功能是为其他函数添加新功能
二 、装饰器需要遵循的原则
1、不修改被装饰函数的源代码(开放封闭原则)
2、为被装饰函数添加新功能后,不修改被修饰函数的调用方式
三、实现装饰器知识储备
装饰器=高阶函数+函数嵌套+闭包
四、高阶函数
高阶函数定义:
1、函数接收的参数是一个函数名
2、函数的返回值是一个函数名
3、满足上述条件任意一个,都可称之为高阶函数
def foo(): print('我的函数名作为参数传给高阶函数') def gao_jie1(func): print('我就是高阶函数1,我接收的参数名是%s' %func) func() def gao_jie2(func): print('我就是高阶函数2,我的返回值是%s' %func) return func gao_jie1(foo) gao_jie2(foo)
#高阶函数应用1:把函数当做参数传给高阶函数 import time def foo(): print('from the foo') def timmer(func): start_time=time.time() func() stop_time=time.time() print('函数%s 运行时间是%s' %(func,stop_time-start_time)) timmer(foo) #总结:我们确实为函数foo增加了foo运行时间的功能,但是foo原来的执行方式是foo(),现在我们需要调用高阶函数timmer(foo),改变了函数的调用方式
#高阶函数应用2:把函数名当做参数传给高阶函数,高阶函数直接返回函数名 import time def foo(): print('from the foo') def timmer(func): start_time=time.time() return func stop_time=time.time() print('函数%s 运行时间是%s' %(func,stop_time-start_time)) foo=timmer(foo) foo() #总结:我们确实没有改变foo的调用方式,但是我们也没有为foo增加任何新功能
高阶函数总结
1.函数接收的参数是一个函数名
作用:在不修改函数源代码的前提下,为函数添加新功能,
不足:会改变函数的调用方式
2.函数的返回值是一个函数名
作用:不修改函数的调用方式
不足:不能添加新功能
五、函数嵌套
def father(name): print('from father %s' %name) def son(): print('from son') def grandson(): print('from grandson') grandson() son() father('熊大') #在father 函数里面再定义son 函数 叫做函数嵌套
# def father(name): # print('from father %s' %name) # def son(): # print('from son') # print(locals()) #打印当前层的局部变量 # # father('xiong') def father(name): # print('from father %s' %name) def son(): print('我的爸爸是%s'%name) def grandson(): name = "我自己" print('我的爷爷是%s'%name) grandson() son() father('xiong')
六、闭包
''' 闭包:在一个作用域里放入定义变量,相当于打了一个包 ''' def father(name): def son(): # name='alex' print('我爸爸是 [%s]' %name) def grandson(): name='熊大' print('我爷爷是 [%s]' %name) grandson() son() father('灰太狼')
七、无参装饰器
无参装饰器=高级函数+函数嵌套
基本框架
#这是实现一个装饰器最基本的框架 def timer(func): def wrapper(): func() return wrapper
加上参数
def timer(func): def wrapper(*args,**kwargs): func(*args,**kwargs) return wrapper
加上功能
#这是计算函数运行时间的装饰功能 import time def timer(func): def wrapper(*args,**kwargs): start_time=time.time() func(*args,**kwargs) stop_time=time.time() print('函数[%s],运行时间是[%s]' %(func,stop_time-start_time)) return wrapper
加上返回值 (wrapper() 函数加上return)
import time def timer(func): def wrapper(*args,**kwargs): start_time=time.time() res=func(*args,**kwargs) stop_time=time.time() print('函数[%s],运行时间是[%s]' %(func,stop_time-start_time)) return res return wrapper
使用装饰器
def cal(array): res=0 for i in array: res+=i return res cal=timer(cal) cal(range(10))
语法糖 @
@timer #@timer <===> cal=timer(cal) def cal(array): res=0 for i in array: res+=i return res cal(range(10))
代码运行过程:
import time def timmer(func): #func=test1 def wrapper(*args,**kwargs): #test('linhaifeng',age=18) args=('linhaifeng') kwargs={'age':18} start_time=time.time() res=func(*args,**kwargs) #就是在运行test() func(*('linhaifeng'),**{'age':18}) stop_time = time.time() print('运行时间是%s' %(stop_time-start_time)) return res return wrapper def test(name,age): time.sleep(3) print('test函数运行完毕,名字是【%s】 年龄是【%s】' %(name,age)) return '这是test的返回值' test=timmer(test) res=test('linhaifeng',age=18) #就是在运行wrapper('linhaifeng',age=18) print(res) @timmer # ===> test=timmer(test) def test1(name,age,gender): time.sleep(1) print('test1函数运行完毕,名字是【%s】 年龄是【%s】 性别【%s】' %(name,age,gender)) return '这是test1的返回值' res = test1('alex',18,'male') print(res)
补充:*args,**kwargs 传值
def test2(name,age,gender): #test2(*('alex',18,'male','x','y'),**{}) #name,age,gender=('alex',18,'male','x','y') print(name) print(age) print(gender) def test1(*args,**kwargs): print(args) print(kwargs) test2(*args,**kwargs) # test2('alex',18,gender='male') test1('alex',18,'male') #test2(*('alex',18,'male'),**{}) test1('alex',18,gender = 'male') #test2(*('alex',18),**{"gender":'male'})
八、装饰器应用示例
import time user_info = [ {"name":"灰太狼",'passwd':"123"}, {"name":"喜洋洋",'passwd':'456'}, {"name":"红太狼",'passwd':'789'}, {"name":"小灰灰",'passwd':'000'}, {"name":"美羊羊",'passwd':'1314'}, {"name":"懒洋洋",'passwd':'159'}, ] current_state = {"username":None,"login":False} def auth_func(func): def wrapper(*args,**kwargs): if current_state["username"] and current_state["login"]: res = func(*args,**kwargs) return res username = input("输入用户名>>>") passwd = input("输入密码>>>") for item in user_info: if username == item["name"] and passwd == item["passwd"]: current_state["username"] = username current_state["login"] = True res = func(*args, **kwargs) return res else: print("输入的用户名或密码错误,请重新输入!") return wrapper @auth_func #--->index = auth_func(index) def index(): print('开始执行index()函数') time.sleep(1) print("欢迎来到京东主页面。。。") @auth_func def home(name): print('开始执行home()函数') time.sleep(1) print("你好啊%s,欢迎回家!"%name) @auth_func def shopping_car(name,goods): print('开始执行shopping_car()函数') time.sleep(2) print("%s的购物车里面有商品%s"%(name,goods)) index() home("村长") shopping_car("灰太狼",['牛奶','饼干','羊腿']) ####打印结果 输入用户名>>>喜洋洋 输入密码>>>456 开始执行index()函数 欢迎来到京东主页面。。。 开始执行home()函数 你好啊村长,欢迎回家! 开始执行shopping_car()函数 灰太狼的购物车里面有商品['牛奶', '饼干', '羊腿']
import time f = open("filedb",'r+',encoding="utf8") userInfo = f.readlines() f.close() current_state = {"username":None,"login":False} def auth(auth_type = "filedb"): def auth_func(func): def wrapper(*args,**kwargs): if current_state["username"] and current_state["login"]: res = func(*args,**kwargs) return res username = input("输入用户名>>>") passwd = input("输入密码>>>") for item in userInfo: if username == eval(item)['name'] and passwd == eval(item)['passwd']: current_state["username"] = username current_state["login"] = True res = func(*args, **kwargs) return res else: print("输入的用户名或密码错误,请重新输入!") return wrapper return auth_func @auth(auth_type="filedb") #@auth(auth_type="filedb")--->auth_func 附加了一个auth_type参数 --->index=auth_func(index) def index(): print('开始执行index()函数') time.sleep(1) print("欢迎来到京东主页面。。。") @auth(auth_type="filedb") def home(name): print('开始执行home()函数') time.sleep(1) print("你好啊%s,欢迎回家!"%name) @auth(auth_type="filedb") def shopping_car(name,goods): print('开始执行shopping_car()函数') time.sleep(2) print("%s的购物车里面有商品%s"%(name,goods)) index() home("村长") shopping_car("灰太狼",['牛奶','饼干','羊腿'])
{"name":"灰太狼",'passwd':"123"} {"name":"喜洋洋",'passwd':'456'} {"name":"红太狼",'passwd':'789'} {"name":"小灰灰",'passwd':'000'} {"name":"美羊羊",'passwd':'1314'} {"name":"懒洋洋",'passwd':'159'}
九、超时装饰器
十、Python内置的装饰器
链接: 静态属性(@property)、类方法(@classmethod)、静态方法(@staticmethod)
参考:
https://www.cnblogs.com/linhaifeng/articles/6140395.html#_label8