函数 (三) 装饰器
时间:2022-05-08
本文章向大家介绍函数 (三) 装饰器,主要内容包括一 为何要用装饰器、二 什么是装饰器、三 装饰器的使用、四、装饰器语法及固定格式、五、应用练习、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
一 为何要用装饰器
有的时候写完一段代码,过段时间需要对它进行升级、添加一些新功能,但是如果要直接修改原来的代码会影响其他人的调用,所以就需要一个不修改源代码且不修改原函数的调用方式的东西又能为原函数增添新功能的东西,装饰器就是干这个的。
二 什么是装饰器
装饰器他人的器具,本身可以是任意可调用对象,被装饰者也可以是任意可调用对象。
强调装饰器的原则:1 不修改被装饰对象的源代码 2 不修改被装饰对象的调用方式
装饰器的目标:在遵循1和2的前提下,为被装饰对象添加上新功能
三 装饰器的使用
下面是为一个函数添加装饰器,添加了计算其运行时间的功能:
1 import time
2 def timmer(func):
3 def wrapper(*args,**kwargs):
4 start_time=time.time()
5 res=func(*args,**kwargs)
6 stop_time=time.time()
7 print('run time is %s' %(stop_time-start_time))
8 return res
9 return wrapper
10
11 @timmer
12 def foo():
13 time.sleep(3)
14 print('from foo')
15 foo()
四、装饰器语法及固定格式
1 def 装饰器函数名(func):
2 def wrapper(*args,**kwargs):
3 ret = func(*args,**kwargs)
4 return ret
5 return wrapper
6
7 @装饰器函数名
8 def func():
9 pass
五、应用练习
1 #######################################作业练习#######################################################
2 #
3 # 1.编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码
4 # user_exist = [False]
5 # def auth(func):
6 # def wrapper(*args,**kwargs):
7 # #注册功能
8 # with open('db.txt','r',encoding='utf-8') as f:
9 # user_dic = eval(f.read())
10 # flag = False
11 # while not user_exist[0]:
12 # username = input('请输入您的用户名:').strip()
13 # password = input('请输入您的密码:').strip()
14 # if username in user_dic and password == user_dic[username]:
15 # print('恭喜您,登录成功!')
16 # user_exist[0] = True
17 # break
18 # else:
19 # print('账号或密码错误,请重新输入!')
20 # ret = func(*args,**kwargs)
21 # return ret
22 # return wrapper
23 #
24 # @auth
25 # def func1():
26 # print('函数1')
27 # @auth
28 # def func2(x):
29 # print('函数2',x)
30 # func1()
31 # func2(111111)
32 # 2.编写装饰器,为多个函数加上记录调用功能,要求每次调用函数都将被调用的函数名称写入文件
33 # def log(func):
34 # def wrapper(*args,**kwargs):
35 # with open('db2.txt','a',encoding='utf-8') as f:
36 # f.write('%s函数正在被调用。n'%func.__name__)
37 # ret = func(*args,**kwargs)
38 # return ret
39 # return wrapper
40 # @log
41 # def func1():
42 # print('func1函数被调用了。。。。')
43 # @log
44 # def func2():
45 # print('func2函数被调用了。。。。')
46 #
47 # func1()
48 # func2()
49 # 进阶作业(选做):
50 # 1.编写下载网页内容的函数,要求功能是:用户传入一个url,函数返回下载页面的结果
51 from urllib.request import urlopen
52
53 # def get_html(url):
54 # print(urlopen(url).read())
55 #
56 # get_html('http://www.baidu.com')
57 # 2.为题目1编写装饰器,实现缓存网页内容的功能:
58 # 具体:实现下载的页面存放于文件中,如果文件内有值(文件大小不为0),就优先从文件中读取网页内容,否则,就去下载,然后存到文件中
59 # from urllib.request import urlopen
60 #
61 # def get_bak(func):
62 # def wrapper(*args,**kwargs):
63 # with open('html.bak','r+',encoding='utf-8') as f:
64 # if not f.read():
65 # ret = func(*args, **kwargs)
66 # print(ret)
67 # f.write(ret.decode('utf-8'))
68 # else:
69 # print('以下内容是从缓存中获得的^^^^^')
70 # f.seek(0)
71 # print(f.read())
72 # ret = func(*args, **kwargs)
73 # return ret
74 # return wrapper
75 #
76 # @get_bak
77 # def get_html(url):
78 # return urlopen(url).read()
79 # get_html('http://www.python.org')
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Windows10安装JDK14
- IDEA 配置 maven 完美解决方案
- 06 Spring Boot 整合Shrio
- List集合转化为数组
- 小心,99%的面试者,都倒在了这里。一文带你了解spring全家桶
- 阿里P9整理Java 高频面试题聊一聊 JUC 下的 LinkedBlockingQueue
- Java环境配置
- 一次django内存异常排查
- Hystrix服务降级-服务熔断
- 自定义值类型一定不要忘了重写Equals,否则性能和空间双双堪忧
- brk实现
- MapReduce之WritableComparable排序
- MapReduce之Combiner合并
- 05 Spring Boot 整合Spring Security
- 无分类编址 CIDR(构造超网)