迭代器 生成器
·复习
1,为什么要要装饰器
软件一旦上线,就应该遵循开放封闭原则,对扩展开放封闭原则,对扩展开放,对修改源代码以及使用方式是封闭的2,什么是装饰器?
器=》工具,装饰=》增加功能
1,不修改源代码
2, 不修改调用方式
装饰器在遵循1和2原则的基础上为装饰对象增加功能的工具
3,实现无装饰器
1,无参装饰器的模板
def outter(func):
def wrapper(*args,**kwargs):
res=func(*args,**kwargs)
return res
return wrapper
2,使用:在被装饰对象的正上方单独一行
4、实现有参装饰器
1、有参装饰器的模板
def outter2(x,y,z):
def outter(func):
def wrapper(*args,**kwargs):
res=func(*args,**kwargs)
return res
return wrapper
return outter
2、使用:在被装饰对象正上方单独一行
@有参装饰器名(1,2,3)
def foo():
pass
迭代器?
什么是迭代?:迭代是一个重复的过程,并且每一次重复都是基于上一次的结果的而来
while True:
print('=====>')
l={'x':1,'y':2}
n=0
while n<len(1):
print(l[n])
n+=1
#可迭代的对象:在python中,但凡内置有__iter__方法的对象,都是可迭代的对象
num=1
#以下都是可迭代的对象
str1='hello'
listl=[1,2,3]
tupl=(1,2,3)
dic={'a','b','c'}
f=open('a.txt','w',encoding='utf-8')
#3迭代器:迭代取值工具,可迭代的对象执行__iter__方法得到的返回值就是迭代器对象
dic={'x':1,'y':2,'z':3}
iter_dic=dic.__iter__()
print(iter_dic.__next__())
print(iter_dic.__next__())
sl={'a','b','c'}
iter_sl=sl.__iter__()
print(iter_sl.__next__())
print(iter_sl.__next__())
listl=[1,2,3]
iter_listl=listl.__iter__()
print(iter_listl.__next__())
#可迭代的对象:str list tuple dict set file
#1,获取可迭代对象的方式:不需要获取,python内置 str list tuple dict set file
# 特点:内置__iter__方法的都叫可迭代的对象,执行该方法可以拿到一个可迭代对象
# 可迭代对象: 文件对象本身就是可迭代对象
# 1获取迭代器对象的方式:
# 执行可迭代对象的__iter__方法,拿到的返回值就是迭代器对象
# 2、特点:
# 内置有__next__方法,执行该方法会拿到迭代器对象中的一个值
# 内置有__iter__方法,执行该方法会拿到迭代器本身
x='hello'
iter_x=x.__iter__()
iter_x.__next__()
print(iter_x.__iter__().__iter__().__iter__())
#文件本身就是迭代器对象
strl='hello'
listl=[1,2,3]
tupl=(1,2,3)
dic={'x':1}
s1={'a','b','c'}
f=open('a.txt','w',encoding='utf-8')
f.__next__()
迭代器的优缺点分析
#迭代器的优点:
#提供了一种可不依赖于索引的取值方式
l=open('a.txt','r',encoding='utf-8')
iter_l=l.__iter__()
while True:
try:
print(iter_l.__next__())
except StopIteration:
break
l=[1,2,3,4,5]
iter_l=l.__iter__()
print(iter_l)
print(iter_l.__next__())
f=open('a.txt')
#迭代器更加节省内存
iter=range(o.10000000000000)
print(iter)
#迭代器缺点,
# 只能一个一个取 取值麻烦,只能往后取,
# 并且是一次性的,无法用len获取长度
x=[1,2,3]
iter_x=x.__iter__()
while True:
try:
print(iter_x.__next__())
except StopIteration:
break
print('第二次======')
iter_x=x.__iter__()
while True:
try:
print(iter_x.__next__())
except StopIteration:
break
for 循环原理
for 循环称之为迭代器循环,in后跟的必须是可迭代的对象
for循环会执行in后对象的__iter__方法,拿到迭代器对象
然后调用迭代器对象的__next__方法,拿到一个返回值赋值给line,执行一次循环体
周而复始,直到取值完毕,for循环会检测到异常自动结束循环
l=open('a.txt','r',encoding='utf-8')
for line in l :
print(line)
for iter in {'x':1,'y':2}:
print(iter)
生成器
函数内包含有yield关键字
在调用函数,就不会执行函数体代码,拿到的返回值就是一个生成器对象
def chicken():
print('====first')
yield
print('====>dhfd')
yield
ojb=chicken()
print(obj)
生成器本质就是迭代器,也就是说生成器的玩法其实就是迭代器的玩法
print(obj.__iter__()is obj)
res=obj.__next__()
print(res)
res1=obj.__next__()
print(res1)
1、iter_obj=obj.__iter__(),拿到迭代器
2、出发iter_obj.__next__(),拿到该方法的返回值,赋值给item
3、周而复始,直到函数内不在有yield,即取值完毕
4、for会检测到StopIteration异常,结束循环
for item in obj:
print(item)
总结yield:
1、为我们提供了一种自定义迭代器的方式,
可以在函数内用yield关键字,调用函数拿到的结果就是一个生成器,生成器就是迭代器
2、yield可以像return一样用于返回值,区别是return只能返回一次值,而yield可返回多次
因为yield可以保存函数执行的状态
def my_range():
print('start....')
n=0
while True:
yield n
n+=1
obj=my_range()
print(obj)
print(obj.__next__())
print(obj.__next__())
for i in my_range():
print(i)
1 面向过程的编程思想
核心是'过程'二字,过程即解决问题的步骤,即先干什么,再干什么
基于面向过程编写程序就好比在设计一条流水线,是一种机械式的思维方式。
2、总结优缺点:
优点:复杂的问题流程化,进而简单化
缺点:修改一个阶段,其他阶段都有可能需要做出修改,牵一发而动全身,即扩展性极差
应用:用于扩展性要求低的场景
拿到用户输入的合法的信息:用户名、密码、余额、年龄
db_path='db.txt'
def get_uanmt():
while True:
uname=input('用户名: ').strip()
if not uname.isalpha():
print('必须是字母')
continue
with open(db_path,mode='r',encoding='utf-8')as f:
for line in f:
uinfo=line.strip('\n').strip(',')
if uname==uinfo[0]:
print('用户已经存在')
break
else:
return uname
def get_pwd():
while True:
pwd1=input('输入密码:')
pwd2=input('确定密码:')
if pwd1==pwd2:
return pwd1
else:
print('两次密码不一样,重新输入')
def get_bal():
while True:
bal=input('请输入余额:')
if bal.isdigit():
return bal
else:
print('钱是数字,傻')
def file_hanle(uname,pwd,bal,age):
with open(r'%s' %db_path,'a',encoding='utf-8')as f:
f.write('%s,%s,%s' %(uname,pwd,bal))
注册功能
def register():
uname=get_uanmt()
pwd=get_pwd()
bal=get_bal()
register()