python day14
带参装饰器
装饰器主要是为被装饰函数添加新功能,有时候也是需要外界提供的参数
当需要外界提供参数时:
1、装饰器函数(outer)只能有一个形参,为了让被装饰函数对象传进去
2、装饰器内部的闭包函数(inner)的参数也是固定的和被装饰函数的参数一直
--以上两个都靠不住的时候,我们就把整个装饰器作为一个整体,嵌套定义在另一个函数的内部,通过外部的函数对里面的函数进行传参
def warps(info): def outer(func): def inner(*args, **kwargs): # 添加新功能 可以接收info进行操作 res = func(*args, **kwargs) # 添加新功能 return res # 可以对结果进行修改 return inner return outer #把装饰器函数传到外界 @warps(info) #括号里面传参,函数遇到括号就执行,返回outer def fn(): #所以实际上@warps(info) = @outer 和之前是一样的 pass fn()
系统的wraps带参装饰器,改变inner的假指向,本质上外界使用的还是inner,但是打印__doc__()和地址都改成wraps()括号里的函数。
form functools import wraps
def outer(func):
@wraps(func) # 改变inner的假指向,doc(文档注释)和地址假指func
def inner(*args,**kwargs):
res = func(*args,**kwargs)
return res
return inner
迭代器
#可迭代对象 可以通过某种方法得到迭代器对象
#迭代器对象 可以不用依赖索进行取值的容器
--迭代器的优点:可以不依赖索引进行取值
--迭代器的缺点:取值只能从前到后取,不能取特定地方的值
可迭代对象
#可迭代对象:有__iter__()方法的对象是可迭代对象,可迭代对象调用__iter__()得到迭代器对象
ls = [1,2,3,4]
res = ls.__iter__() ==>ls有iter的方法,所以ls(列表list)是可迭代对象
直接访问res是访问 得到的迭代器对象 的地址
#可迭代对象有哪些:字符串(str)、列表(list)、元组(tuple)、字典(dict)、集合(set)、 迭代器对象、生成器对象
迭代器对象
#迭代器对象:有__next__()方法的对象是迭代器对象,迭代器对象可以用__next__()方法进行取值
with open('1.txt','rb') as f:
res = f.__next__() #文件中第一行的内容
print(res)
res = f.__next__() #文件中第二行的内容
print(res)
#迭代器的对象有哪些:文件对象、枚举对象(enumerate(s))
for循环迭代器
#直接用while循环在迭代器对象中通过__next__()取值,终究会有取完的时候,取完再取
就会抛出StopIteration异常
ls = [1,2,3,4] iterator = ls.__iter__() #先把ls变成迭代器对象 while True: try: #取完会报StopIteration异常,用try except语法来捕捉异常 print(iterator.__next__()) #通过while循环取值 except StopIteration: #捕捉到异常之后结束循环 break
所以for循环就是对while取迭代器的封装
ls = [1,2,3,4] for v in ls: print(v) for v in ls.__iter__(): #->可迭代对象取完就是迭代器对象 print(v) iterator = ls.__iter__() #->迭代器对象取完就是本身 (三个循环取值的结果都是一样的) for v in iterator: print(v)
for循环迭代器取值的工作原理
for v in obj:pass
#1、获取obj__iter__()的结果, 就是得到要操作的迭代器对象
#2、迭代器对象通过__next__()方法进行取值,依次将当前循环的结果赋值给v
#3、当取值抛出异常之后,自动处理StopIteration异常并结束循环
枚举对象
#给可迭代对象及迭代器添加迭代索引
s = 'abc'
for v in enumerate(s):
print(v) #(0,'a') (1,'b') (2,'c')
生成器
生成器:语法和函数相同,内部有yield关键字,函数名()得到的是生成器对象,生成器对象也有next方法所以:
--生成器就是自定义的迭代器对象
--就是用函数语法来声明生成器,用yield关键字取代return关键字来返回值,参数没有多少变化
#执行流程
def fn():
yield 1 #从上往下执行,遇到一个yield返回一个值
yield 2 #然后再取找下一个yield,再返回一个值
yield 3 #如果找不到yield,就会抛异常stopiteration
#和for连用的话for会自动处理Stopiteration异常并结束循环
range()就是一个系统的生成器,我们也可以自己定义一个和range功能一样的生成器