py 5.16
一、可迭代对象。迭代器。
#可迭代对象:dir()中含有__iter__方法。 # li = '589494' # print('__iter__' in dir(li)) from collections import Iterable from collections import Iterator # print(isinstance(li,Iterator)) #转换成迭代器: # l_obj = li.__iter__() #迭代器的特点:节省内存、惰性机制(取完值以后再取不从头开始取)、单向不可逆 #迭代器的取值方法 #一、用__next__()一个一个的取 ## print(l_obj.__next__()) #下次再取就从上次结束的地方继续往下取 #二、用for循环依次一起输出 # for i in l_obj: # print(i) #一般的可迭代对象其实是不可以用for来遍历的,只有变成迭代器才可以。所以,for循环可迭代对象时,内部 #有这样的机制: #1、将可迭代对象转换成迭代器: l_obj = li.__iter__() #2、用__next__()方法每循环一次取一次值。 #3、用try方法防止报错:(while循环模拟for机制) # while True: # try: #用try来防止next循环到最后找不到报错。 # print(l_obj.__next__()) # except Exception: #Exception代表万能错误。只要遇到错误就走break. # break #打开文件生成的文件句柄是可迭代对象也是迭代器。
二、生成器
#生成器 #生成器本质也是迭代器,是自己用python写出来的迭代器(以前的迭代器是一些自己转化过来的迭代器) #两种方法,第一种:用生成器函数。 yield # def func(): # print(111) # yield 222 #遇见一个yield返回一个生成器对象,然后对生成器对象进行取值(next或者for) # yield 333 # yield 444 # g = func() #返回值赋值给g,g成为生成器对象 # print(g.__next__()) #每打印一个next执行一个yield # print(g.__next__()) # def func(): # for i in range(1,21): #这里的range是代表一共有多少值。 # yield i # g = func() # for j in range(1,11): #这里的range是为了控制取值次数 # print(g.__next__()) #打印前十个 # for j in range(1,11): # print(g.__next__()) #接着打印后十个 #send 和 next #1.send与next功能一样 #2.send可以传值给上一个yield. #3.第一个必须用next不能用send. #4.最后一个yield不能得到send的值。 # def func(): # count =yield 111 #send取值的时候传给了yield一个值:2, 所以count = 2 # print(count) #count = 2 # yield 222 #此处用send取值,同时传给上一个yield一个值。 # yield 333 # g = func() # print(g.__next__()) #第一个必须用next取值 # print(g.send(2)) #send与next的功能一样,可以取第二个值222,括号中的2传给上一个yield. #生成器生成的第二种方法:推倒式 #列表推倒式 [] # li = [i for i in range(1,101) if i % 2 == 0] #将100以内所有的偶数加到列表中。 # print(li) # lis = [] # for i in range(1,12): # lis.append(i) # print(lis) # lis = ['python第%d期' % i for i in range(1,13)] # print(lis) # lis = ['taibai','alex','nvshen'] # lis1 = [i+'NB' for i in lis] # print(lis1) # lis = [i for i in range(1,101) if i % 2 == 1] # print(lis) # lis = [i**2 for i in range(1,10)] # print(lis) # lis = [i**2 for i in range(1,31) if i % 3 == 0]# names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'], # ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']] # lis = [name for i in names for name in i if name.count('e') == 2] # print(lis) #生成器推倒式 () # g =(i for i in range(1,101) if i % 2 == 0) #将100内的偶数变成一个生成器对象,然后按需要取值。 # print(g.__next__()) # print(g.__next__())
三、知识点补充
#补充: #1.装饰器本质是闭包。 #2.开放封闭原则: # 1.对扩展是开放的 # 为什么要对扩展开放呢? # 我们说,任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改。 # 所以我们必须允许代码扩展、添加新功能。 # 2.对修改是封闭的 # 为什么要对修改封闭呢? # 就像我们刚刚提到的,因为我们写的一个函数,很有可能已经交付给其他人使用了, # 如果这个时候我们对其进行了修改,很有可能影响其他已经在使用该函数的用户。 # 装饰器完美的遵循了这个开放封闭原则。 #globals() / locals() #globals():打印当前位置的所有的全局变量。(在局部中使用也是打印全局的) #locals():打印当前位置的所有的局部变量。(在全局中使用也可打印全局的) # count = 1 # ret = 2 # def func(): # i = 4 # a = 3 # print(locals()) #以键值对的形式打印一个字典 # print(globals()) #当前位置的所有全局变量 #如,输出{count: 1} # func() # print(globals()) #字典。打印当前位置前的所有的本页中的全局变量 #输出{count: 1} # print(locals()) #locals()放在全局中输出的值等同于globals() #输出{count: 1}