一、迭代器和生成器
(一)迭代器
➢ 迭代器指的是迭代取值的工具
➢ 迭代是一个重复的过程,每一次重复都是基于上一次的结果而来
➢ 可迭代的对象:str,list,tuple,dict,set,文件对象
➢ 执行可迭代对象下的__iter__方法,返回的值就是一个迭代器对象iterator
dic = {'x': 1, 'y': 2, 'z': 3}
iter_dic = dic.__iter__()
print(iter_dic) #迭代器内存地址
print(iter_dic.__next__())
print(iter_dic.__next__())
print(iter_dic.__next__())
l = ['a', 'b', 'c']
print(l.__iter__().__next__())
print(l.__iter__().__next__())
print(l.__iter__().__next__())#这三行是一样的结果
iter_l = l.__iter__()
print(iter_l.__next__())
print(iter_l.__next__())
print(iter_l.__next__())#这三行结果不一样
注意!!
➢ 1.迭代器对象一定是可迭代的对象,而可迭代的对象却不一定是迭代器对象
可迭代的对象:__next __、__iter __
迭代器对象:__next __
➢ 2.文件对象本身就是一个迭代器对象
iter_l = l.__iter__()
print(iter_l is iter_l.__iter__().__iter__())#几个.__iter__()返回的都是true
dic = {1, 2, 3, 4}
l = {'x': 1, 'y': 2, 'z': 3}
print(len(dic))#dic.__len__()
iter_dic = iter(dic)#dic.__iter__()
while True:
try:
print(next(iter_dic))#dic.__iter__()
except StopIteration:
break
print('='*100)
#同一个迭代器只能完整的取完一次值
iter_dic = iter(l)#dic.__iter__()
while True:
try:
print(next(iter_dic))#iter_dic.__next__()
except StopIteration:
break
优点:
➢ 1. 提供一种通用的且不依赖于索引的迭代取值方式
➢ 2. 同一时刻在内存中只存在一个值,更节省内存
缺点:
➢ 1. 取值不如按照索引的方式灵活,(不能取指定的某一个值,而且只能往后取)
➢ 2. 无法预测迭代器的长度
(二)生成器
➢ 生成器就是一种自定义的迭代器,本质就是迭代器
➢ 但凡函数内包含yield关键字,调用函数不会执行函数体代码,会得到一个返回值,该返回值就是
生成器对象
def my_range(start, stop, step=1):
while start < stop:
yield start#yield也是返回值,可理解为光标停在start值后
start += step
obj = my_range(1, 15, 2)
print(next(obj))
print(next(obj))
print(next(obj))
print(next(obj))
yield总结:只能在函数内部使用
➢ 1. yield提供了一种自定义迭代器的解决方案
➢ 2. yield可以保存函数的暂停的状态
➢ 3. yield对比return
1). 相同点:都可以返回值,值的类型与个数都没有限制
2). 不同点:yield可以返回多次值,而return只能返回一次值函数就结束了
二、闭包和装饰器
(一)闭包
➢ 一个函数内部又定义了一个函数
➢ 第一层函数的返回值是内层函数的函数名(注意:不加括号)
def index():
print('welcome to index page')
time.sleep(3)#时间停止3秒
def outter(func):
def wrapper():
start = time.time()
func()
stop = time.time()
print('run time is %s'%(stop - start))
return wrapper#这里注意,不加括号
index = outter(index)
index()
(二)装饰器
1、概念
➢ 器:指的是具备某一功能的工具
➢ 装饰:指的是为了被装饰器对象添加新功能
➢ 总结:装饰器就是用来为被装饰器对象添加新功能的工具
➢ 注意:装饰器本身可以是任意可调用对象,被装饰器的对象也可以是任意可调用对象
2、作用
➢ 开放封闭原则:封闭指的是对修改封闭,对扩展开放
3、装饰器的实现必须遵循两大原则:
➢ 1. 不修改被装饰对象的源代码
➢ 2. 不修改被装饰器对象的调用方式
4、 装饰器的目标:
就是在遵循两大原则的前提下为被装饰对象添加上新功能
5、装饰器的语法糖
➢ 装饰器的语法糖:在被装饰对象的正上方单独一行写@装饰器的名字
➢ 运行原理:
➢ python解释器一旦运行到@装饰器的名字,就会调用装饰器,然后将被装饰函数的内存地址当作
参数传给装饰器,最后将装饰器调用的结果赋值给原函数名
def outter(func):
def war(*args, **kwargs):
res = func(*args, **kwargs)
return res
return war
@outter
def home(name):
return name
print(home('jane'))
print(outter(home('jane')))
import time
#装饰器模板
def outter(func):
def wrapper(*args, **kwargs):
#在调用函数前加功能
res = func(*args, **kwargs)#调用被装饰的\也就是最原始的那个函数
#在调用函数后加功能
return res
return wrapper
@outter#index=outter(index)#index =wrapper
def index():
print('welcome to index page')
time.sleep(3)
叠加多个装饰器
➢ @装饰器语法糖是自下而上运行的
➢ 而装饰器内的那个wrapper函数是自上而下运行的
➢ 运行完被装饰函数以后的代码是自下而上运行
import time
def outter1(func1):
print('outter1')
def wrapper1(*args, **kwargs):
print('wrapper1')
res1 = func1(*args, **kwargs)
print('endwrapper1')
return res1
return wrapper1
def outter2(func2):
print('outter2')
def wrapper2(*args, **kwargs):
print('wrapper2')
res2 = func2(*args, **kwargs)
print('endwrapper2')
return res2
return wrapper2
@outter1
@outter2
def index():
print('welcome to index page')
time.sleep(3)
index()
三、模块和包
模块
1、模块的两种导入方式
(1)import导入
import 模块名1,模块名2
import 模块名1
import 模块名2
使用as指定模块的别名
如果模块的名字太长,可以使用as指定模块的名称,以方便在代码中的使用
注意:模块别名 应符合 大驼峰命名法
import 模块名1 as 模块别名
(2)from…import导入
从一个模块中导入部分工具
from 模块名1 import 工具名
注意:如果两个模块存在同名的 函数,那么后导入模块的函数会覆盖掉先导入的函数
from…import *(知道)
#从模块 导入 所有工具
from 模块名1 import *
这种方式不推荐使用,因为函数重名没有提示,出现问题不好排查
包package
四、常用模块
1、time模块
import time
print(time.localtime(time.time()))
#时间戳
print(time.time())
#获取本地时间的格式
print(time.strftime('%Y-%m-%d %H:%M:%S'))
import datetime
#当前时间的具体时间
print(datetime.datetime.now())
#时间的加减
print(datetime.datetime.now()+datetime.timedelta(days=30, hours=1, minutes=1, seconds=1))
2、datetime模块
3、sys模块
4、os模块
5、path模块
6、random 模块
import random
#不用加参数0,1不包含0
print(random.random())
#0,3闭闭
print(random.randint(0, 3))
#1,4闭开
print(random.randrange(1, 4))
'''从列表里随机取一个值'''
print(random.choice([1,2,3, 'rua']))
#从列表里面随机取两个值
print(random.sample([1,2,3,'haha'],2))
#1,3闭闭浮点数
print(random.uniform(1,3))