迭代器、迭代对象、闭包的应用、装饰器

来源:互联网 发布:sql 父子级联查询 编辑:程序博客网 时间:2024/06/04 20:05

可迭代对象才可以用for进行访问

迭代对象:可以遍历位置的对象,可以由上一个元素继续遍历下一个元素位置

迭代器:可以被next函数调用并不断返回下一个值的对象称为迭代器:Iterator


#迭代是访问集合元素的一种方式,迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,#直到所有的元素被访问完结束,迭代器只能往前不会后退。#可迭代对象#1 集合数据类型:list tuple dict set str#2 一类是generator,包括生成器和带yield的generator function#可以直接作用于for循环的对象统称为可迭代对象:iterable##迭代的意思是可以在上一个基础上进行下一个的处理for i in "ab":print(i)for i in [11,22]:print(i)for i in (22,33):print(i)for i in {'h':1}:print(i)for i in {113,223}:print(i)#上面的说明都可以完成迭代a=[x for x in range(8)]#列表生成器b=(x for x in range(8))#生成器for temp in b:print(temp)   #生成器也可以迭代#判断是否可以迭代 ,可以用for循环访问#2 用isinstance()判断一个对象是否是iterablefrom collections import Iterableprint(isinstance([],Iterable))#Trueprint(isinstance({},Iterable))#Trueprint(isinstance('abc',Iterable))#Trueprint(isinstance((x for x in range(10)),Iterable))#Trueprint(isinstance(100,Iterable))#False#迭代器#可以被next函数调用并不断返回下一个值的对象称为迭代器:Iterator#可以使用isinstance判断一个对象是否是iterator对象#生成器是迭代器,list dict str是Iterable,不是Iteratorfrom collections import Iteratorisinstance((x for x in range(10)),Iterator)#trueisinstance([],Iterator)#False#可以把list、dict、str等Iterable变成Iterator,使用iter()函数isinstance(iter([]),Iterator) #Trueisinstance(iter('abd'),Iterator) #Trueli=[10,2,2,344]itera=iter(li)print(next(itera)) #10  使用这种方式访问,占用的内存比列表少print(next(itera))#2print(next(itera))#2print(next(itera))#344

闭包的应用

先看一个例子

#定义一个函数def test():print("这里的函数名仅仅是指向定义的这个函数块而已")test()print(test)#<function test at 0x000000000117D1E0>b=test #test b 都指向了函数体b()#正常的执行test()函数

闭包:提高了代码的可复用性

def test(number):print("this is the test content")def test_in(number2):print("this is a test in the test")print(number+number2)print("this is also in the test")return test_inret=test(100)#ret是返回的指向的函数,函数test_in()与number构成了闭包ret(200)''' 显示结果:this is the test contentthis is also in the testthis is a test in the test300'''

闭包的使用实例


def test(a,b):def test_in(x):print(a*x+b)return test_inline1=test(1,1)line1(9) #相当于计算1*9+1line2=test(10,4)#若程序还在使用,则创建新的对象,若没有使用,则修改之前创建对象的内容line2(3) #相当于计算10*3+4


闭包思考:

1.闭包似优化了变量,原来需要类对象完成的工作,闭包也可以完成2.由于闭包引用了外部函数的局部变量,则外部函数的局部变量没有及时释放,消耗内存

使用原来的方法,需要写一个函数,传递3个参数

装饰器

#装饰器对于项目的效率提高有很大作用,是程序开发的基础#若函数中定义了两个重命名的函数,比如两个test#第一个test指向第一个函数体,然后test指向第二个函数体#函数test最终指向后一个函数体,调用后一个函数体##python中函数名字相同的话,不会抛异常##代码的开放封闭原则:已经实现的功能代码不允许被修改,但可以被扩展#封闭:已实现的功能代码块#开放:对扩展开发#def w1(func):  #这里w1指向一个定义的函数体def inner():#inner指向一个函数体print("----正在验证---")func() #执行func指向的函数体return inner#返回一个函数体def f1():#f1指向一个函数体print("---f1----")def f2():#f2指向一个函数体print("---f2----")f1=w1(f1)f1=()

采用语法糖,装饰器来处理

@函数名 是python的一种语法糖
1 执行ww1函数,将@ww1下面的函数作为ww1函数的参数:@ww1等价于ww1(ff1)
2 将执行完的ww1函数的返回值赋值给@ww1下面的函数的函数名ff1,即将ww1的返回值再次赋值给ff1


#采用另外一种方式def ww1(func):  #这里w1指向一个定义的函数体def inner():#inner指向一个函数体print("----正在验证---")func() #执行func指向的函数体return inner#返回一个函数体@ww1def ff1():#f1指向一个函数体print("---f1----")@ww1def ff2():#f2指向一个函数体print("---f2----")#@函数名 是python的一种语法糖#1 执行ww1函数,将@ww1下面的函数作为ww1函数的参数:@ww1等价于ww1(ff1)#2 将执行完的ww1函数的返回值赋值给@ww1下面的函数的函数名ff1,即将ww1的返回值再次赋值给ff1#ff1()ff2()'''显示结果:----正在验证------f1--------正在验证------f2----'''

2个装饰器

#对于装饰器def makeBold(fn):def wrapped():return "<b>"+fn()+"</b>"return wrappeddef makeItalic(fn):def wrapped():return "<i>"+fn()+"</i>"return wrapped@makeBold@makeItalicdef testBI():return "hello world"print(testBI())#<b><i>hello world</i></b>


多个装饰器

#对于装饰器def makeBold(fn):print("正在装饰1")def wrapped():print("---正在验证权限1---")return "<b>"+fn()+"</b>"return wrappeddef makeItalic(fn):print("正在装饰2")def wrapped():print("----正在验证权限2----")return "<i>"+fn()+"</i>"return wrapped#只要python解释器执行到这个代码,那么就会自动的进行装饰,而不是等到调用的时候才开始装饰#即:在调用testBI之前已经开始装饰了@makeBold     #当@函数时就开始执行,第一个makeBold下面不是函数,没法作为参数,所以继续向下执行@makeItalic  #第一步:testBI=makeItalic(testBI)  第二步:testBI是函数可以传递给makeBold(testBI),这两步实现了装饰:后面testBI()运行def testBI():print("执行test")return "hello world"print(testBI())#<b><i>hello world</i></b>,在这之前已经完成了装饰'''正在装饰2正在装饰1---正在验证权限1-------正在验证权限2----执行test<b><i>hello world</i></b>'''#先装饰第一个,再装饰第二个,再执行原来的函数如testBI()