三器(装饰器,生成器,迭代器)
目录
1. 装饰器
什么是装饰器?
装饰器本质是函数,用来给其他函数添加新的功能
特点:不修改调用方式、不修改源代码
装饰器的应用场景?
用户认证,判断用户是否登录
计算函数运行时间(算是一个功能、在项目里用的不多)
插入日志的时候
redis缓存
为什么使用装饰器?
结合应用场景说需求
比如提高代码复用性,节省内存空间
如何使用装饰器?
装饰器求函数运行时间
1 import time 2 def timer(func): #timer(test1) func=test1 3 def deco(*args,**kwargs): 4 start_time = time.time() 5 func(*args,**kwargs) #run test1 6 stop_time = time.time() 7 print("running time is %s"%(stop_time-start_time)) 8 return deco 9 10 # @timer # test1=timer(test1) 11 def test1(): 12 time.sleep(3) 13 print("in the test1") 14 test1()
三级装饰器
1 #! /usr/bin/env python 2 # -*- coding: utf-8 -*- 3 import time 4 def auth(auth_type): 5 print("auth func:",auth_type) 6 def outer_wrapper(func): 7 def wrapper(*args, **kwargs): 8 print("wrapper func args:", *args, **kwargs) 9 print('运行前') 10 func(*args, **kwargs) 11 print('运行后') 12 return wrapper 13 return outer_wrapper 14 15 @auth(auth_type="local") # home = wrapper() 16 def home(): 17 print("welcome to home page") 18 return "from home" 19 home()
2. 生成器
什么是生成器?
生成器就是一个特殊的迭代器
一个有yield关键字的函数就是一个生成器
生成器,是这样一个函数,它记住上一次返回时在函数体中的位置。
对生成器函数的第二次(或第 n 次)调用跳转至该函数中间,而上次调用的所有局部变量都保持不变。
生成器哪些场景应用?
生成器是一个概念,我们平常写代码可能用的并不多,但是python源码大量使用
比如我们tornado框架就是基于 生成器+协程
在我们代码中使用举例
比如我们要生成一百万个数据,如果用生成器非常节省空间,用列表浪费大量空间
1 import time 2 t1 = time.time() 3 g = (i for i in range(100000000)) 4 t2 = time.time() 5 lst = [i for i in range(100000000)] 6 t3 = time.time() 7 print('生成器时间:',t2 - t1) # 生成器时间: 0.0 8 print('列表时间:',t3 - t2) # 列表时间: 5.821957349777222
为什么使用生成器
节省空间
高效
如何使用?
1 #!/usr/bin/python 2 # -*- coding: utf-8 -*- 3 def read_big_file_v(fname): 4 block_size = 1024 * 8 5 with open(fname,encoding="utf8") as fp: 6 while True: 7 chunk = fp.read(block_size) 8 # 当文件没有更多内容时,read 调用将会返回空字符串 '' 9 if not chunk: 10 break 11 print(chunk) 12 path = r'C:\aaa\luting\edc-backend\tttt.py' 13 read_big_file_v(path)
3. 迭代器
什么是迭代器?
迭代器是访问集合内元素的一种方法
总是从集合内第一个元素访问,直到所有元素都被访问过结束,当调用 __next__而元素返回会引发一个,StopIteration异常
有两个方法:_iter_ _next_
_iter_ : 返回迭代器自身
_next_: 返回下一个元素
应用场景
一些可以直接利用的迭代器
1 无线迭代器生产: 2 无线迭代器------> from itertools import count(接受俩个参数起点和步长) 3 每次调用count都是2从1递增,将所有的基数打印出来,如果说你的内存足够大的话,可以无限迭代下去(可以使用for循环或者next测试),这里推荐使用next,因为它比较直观。
手机号(count)
cycle(塞口),每次调用都会字符串下一个值创建出来,而创建完最后一个,他会返回到开头,像一个圈状的数据类型不停去创建一个新的值
有限迭代器
1 iter() 2 from itertools import islice 3 islice(iterable,stop) 接受参数(可迭代对象,终点值) 4 islice(iterable,start,stop[,step]) 接受参数(可迭代对象,索引,也可以加步长)
基于可迭代对象创建 iter()
使用islice方法
自定义迭代器(斐波那契数列)