一.上次课内容回顾
装饰器
def wrapper(fn): #fn:要装饰的函数
def inner(*args,**kwargs):#接收参数.为了目标函数执行
'''目标函数之前'''
ret=fn(*args,**kwargs)
'''目标函数之后'''
return ret
return inner
@wrapper #func=wrapper(func)
def func():
pass
func()# inner
带参数的装饰器
def wrapper_out(参数):
def wrapper(fn):#fn:要装饰的函数
def inner(*args,**kwargs):# 接收参数.为了目标函数的执行
'''目标函数之前'''
ret=fn(*args,**kwargs)
'''目标函数之后'''
return ret
return inner
return wrapper # 装饰器
@wrapper_out('参数')
def func():
pass
同一个函数被多个装饰器装饰
@wrapper1
@wrapper2
@wrapper3
pass
{[()]}
二.今日主要内容
1.迭代器
可以使用dir()函数来检查类的内部定义的函数
特点:
__iter__() 获取迭代器
__next__()获取最前面这个元素
s='123'
for c in s:
print(c)
使用dir()来查看函数
ret=dir(str)# 字符串中有__iter__() 获取迭代器
print(ret)
我们通过__iter__()来获取到迭代器
s='我昨天去天安门了'
it=s.__iter__()#获取到迭代器
print(it.__next__())#我
print(it.__next__())#昨
print(it.__next__())#天
print(it.__next__())#去
print(it.__next__())#天
print(it.__next__())#安
print(it.__next__())#门
print(it.__next__())#了 最后一个元素之后.继续__next__()报错
for循环是怎么回事儿,要求必须是可迭代对象
for循环的内部.使用的就是迭代器.
最开始.获取迭代器.然后每次执行的时候.都是__next__()
2.生成器(初识)
本质就是迭代器.
yield和return
函数中如果出现了yield.这个函数是生成器函数.
这个时候执行函数.获取到生成器.
使用__next__()执行到下一个yield.send()也有这个功能.
区别:
__next__()不能赋值
send()可以赋值,在执行send()之前执行__next__()
生成器的优点:
节省内存.
def func():
print('111')
return 222
print('333')
ret=func()
print(ret)
def func():
print('111')
yield 222 # 如果函数中有yield这个函数是一个生成器函数
print('333')
yield 444
gen=func()#我们访问生成器函数的时候.函数并不会执行,而是返回一个生成器
#拿到生成器之后.就相当于拿到了迭代器
ret=gen.__next__() #执行到下一个yield,拿到的是222
print(ret)# 生成器
ret2=gen.__next__()
print('ret',ret2)
yield和return的区别
1.如果函数中包含了yield,这个函数是一个生成器函数.执行函数的时候是:生成器
2.生成器执行__next__().执行到下一个yield
3.yield的作用和return基本相同.但是,只负责返回.不会结束函数
4.return,结束函数.
# 老男孩从JACK JONES 订购10000套服装
# def func():
# lst = []
# for i in range(0, 10000):
# lst.append("服装"+str(i))
# return lst
# print(func())
# 老男孩没那么多人, 最好的解决方案. 有一个人, 给一件衣服
# def func():
# for i in range(0, 10000):
# yield "服装"+str(i)
# gen = func() # 生成器
# ret1 = gen.__next__()
# print(ret1)
# ret2 = gen.__next__()
# print(ret2)
# for i in range(0, 65):
# ret = gen.__next__()
# print(ret)
# def eat():
# print("你想吃什么")
# a = yield "想吃什么"
# print("想吃"+str(a))
# b = yield "还想吃什么"
# print("还想吃"+ str(b))
# c = yield "吃饱了"
#
#
# gen = eat()
# gen.__next__()
# gen.send("面条")
# ret = gen.send("饺子")
# print(ret)
#
# gen = eat() # 获取生成器
# # 第一次调用必须使用__next__()
# r1 = gen.__next__()
# print(r1)
# r2 = gen.send("驴肉火烧") # 能传值
# print(r2)
# r3 = gen.send("麻花藤")
# print(r3)
# gen.__next__() # 如果函数的最后没有yield 会报错
# send() 和__next__()一样. 也是执行到下一个yield
# send和__next__() 区别:
# send可以给上一个yield 的位置传递值 , 第一个必须用__next__()
# __next__() 不能传值
def jiaoyou():
print("开始旅游")
address1 = yield "告诉我你想去哪里"
print("去"+str(address1))
address2 = yield "你还想去哪儿?"
print("还想去"+ str(address2))
yield "结束旅行"
gen = jiaoyou()
ret = gen.__next__() # 执行到第一个yield 获取到返回值
print("ret=", ret)
ret2 = gen.send("少林寺")
print("ret2 = ", ret2)
ret3 = gen.send("武当山")
print("ret3 = ", ret3)