闭包
内层函数对外层函数的变量(非全局变量)的引用,并返回函数名就形成了闭包。
1 def packet(): 2 name = '孙飞' 3 def inner(): 4 print(name) 5 print(inner.__closure__) #判断是否是闭包,如果是闭包对象则返回一个cell 6 return inner 7 f1 = packet() 8 f1() 9 10 name = 'alex' #全局变量 11 def wraaper(): 12 def inner(): 13 print(name) 14 print(inner.__closure__) # None,非闭包 15 inner() 16 return inner 17 wraaper()
闭包作用:
当程序执行时,遇到了函数执行,他会在内存中开辟一个空间,局部名称空间,
如果这个函数内部形成了闭包,
那么他就不会随着函数的结束而消失。
可迭代对象
1 for i in 'abc': 2 print(i) 3 for i in 123: 4 print(i) # 'int' object is not iterable
对象内部含有__iter__方法就是可迭代对象.
可迭代对象满足可迭代协议。
可迭代对象:str list dict,tuple,set,range()
str= 'abddef'
print(dir(str))
Python下一切皆对象,每个对象都有多个属性(attribute),Python对属性有一套统一的管理方案。
__dict__与dir()的区别:
dir()是一个函数,返回的是list;
__dict__是一个字典,键为属性名,值为属性值;
dir()用来寻找一个对象的所有属性,包括__dict__中的属性,__dict__是dir()的子集;
并不是所有对象都拥有__dict__属性。许多内建类型就没有__dict__属性,如list,此时就需要用dir()来列出对象的所有属性。
判断一个对象是否是可迭代对象:
第一个方法
1 dic = {'name':'alex'} 2 print('__iter__' in dir(s1)) 3 print('__iter__' in dir(dic))
第二种方法
1 from collections import Iterable #注意前面的iterable和iterator首字母要大写I 2 from collections import Iterator 3 4 print(isinstance('alex',Iterable)) # True 5 print(isinstance('alex',Iterator)) # True 6 print(isinstance('alex',str)) 7 isinstance是Python中的一个内建函数
语法:
isinstance(object, classinfo)
如果参数object是classinfo的实例,或者object是classinfo类的子类的一个实例, 返回True。如果object不是一个给定类型的的对象, 则返回结果总是False。
如果classinfo不表示一个类(类型对象), 那么它要么是一个类的元组, 或者递归地包含这样的(由数据类型构成的)元组.其他的序列类型是不被允许的。
如果classinfo不是一种数据类型或者由数据类型构成的元组,将引发一个TypeError异常。
举例:
>> > isinstance(1, int)
True
>> > isinstance(1.0, float)
True
迭代器?
对象内部含有__iter__方法且含有__next__方法就是迭代器.
1 f = open('register', encoding='utf-8') 2 print('__iter__' in dir(f)) 3 print('__next__' in dir(f)) 4 print('__iter__' in dir(dict)) 5 print('__next__' in dir(dict))
可迭代对象vs迭代器
可迭代对象不能取值,迭代器是可以取值的。
可迭代对象 --->(转化成)迭代器
lis = [1, 2, 3] # 可迭代对象# ite1 = lis.__iter__() # 迭代器 #<list_iterator object at 0x0000027A183BFFD0> ite1 = iter(lis) # 迭代器 <list_iterator object at 0x0000027A183BFFD0> print(ite1)
迭代器如何取值? next一次,取一个值
1 print(ite1.__next__()) 2 print(ite1.__next__()) 3 print(ite1.__next__()) 4 print(ite1.__next__())
1, 可迭代对象不能取值,迭代器是可以取值的。
2, 迭代器非常节省内存。
3,迭代器每次只会取一个值。
4,,迭代器单向的,一条路走到头。
1 s1 = 'kfdsjl' 2 for i in s1: 3 print(i)
1,将可迭代对象转化成迭代器。
2,调用__next__方法取值。
3,利用异常处理停止报错。
用while模拟for遍历对象的过程
1 iter1 = s1.__iter__() 2 while 1: 3 try: 4 print(iter1.__next__()) 5 except StopIteration: 6 break
1 l1 = [i for i in range(100)] 2 print(l1) 3 ret =( i for i in range(1000000)) 4 print(ret.__next__()) 5 print(ret.__next__()) 6 print(ret.__next__()) 7 print(ret.__next__()) 8 print(ret.__next__())