Python 从零学起(纯基础) 笔记 之 迭代器、生成器和修饰器

Python的迭代器、 生成器和修饰器


1、 迭代器访问集合元素的一种方式,从第一个到最后,只许前进不许后退

不要求事先准备好整个迭代过程中的所有元素,仅仅在迭代到某个元素时才计算该元素,而在这之前或者之后,元素可以不存在或被销毁。

特点:

  • 访问者是不需要关心迭代器内部的结构,仅需要通过next()方法不断去取下一个内容
  • 不能随机访问集合中的某个值,只能从头到尾依次访问。
  • 访问到一半时不能往回退
  • 便于循环比较大的数据集合,节省内存
1 names = iter(['alex','jack','list'])
2 print(names)
3 print(names.__next__())
4 print(names.__next__())
5 print(names.__next__())

结果:

<list_iterator object at 0x005CC410>

alex

jack

list

2、  生成器

定义:

  一个函数调用时返回一个迭代器,那这个函数就叫做生成器generator),如果函数中包含yield语法,那这个函数就会发生生成器。

作用:

  这个yield的主要效果,就是可以使函数中断,并保存中断状态,中断后,代码可以继续往下执行,过一段时间还可以再重新调用这个函数,从上次yield的下一句开始执行。

例1:

 1 def cash_money(amount):
 2     while amount > 0:
 3         amount -= 100
 4         yield 100
 5         print("取钱啦again")
 6 atm = cash_money(500)
 7 print(type(atm))
 8 print(atm.__next__())
 9 print(atm.__next__())
10 print("go to 相声")
11 print(atm.__next__())

结果:

<class 'generator'>

100

取钱啦again

100

go to 相声

取钱啦again

100

 

一共五百块,先去两百块钱,然后去听相声,之后在回来取100 。 一个循环我可以先跳出去做其他事,然后再回来继续做这件事。

 

例2:用yield实现单线程中的异步

 1 import time
 2 def consumer(name):
 3     print("%s 准备吃包子啦!"%name)
 4     while True:
 5         baozi=yield #接收别人发送给他的值
 6         print("包子%s 来了,被%s吃了!" % (baozi,name))
 7 
 8 def producer(name):
 9     c = consumer('A')
10     c2 = consumer('B')
11     c.__next__()
12     c2.__next__()
13     print("准备做包子啦")
14     for i in range(10):
15         time.sleep(1)
16         print("I finished two baozi!")
17         c.send('Alex')#通过send给yield发送i
18         c2.send(i)
19 
20 producer("Young")

可以设置断点,单步运行查看程序运行的过程

 

3、  装饰器

开放封闭原则:已实现的功能代码不允许被修改,但是可以被扩展

开放:对扩展开放

封闭:以实现的功能代码块

 

没有使用装饰器

 1 def login(func):
 2     print("登录验证.")
 3     return func
 4 
 5 def home(name):
 6     print("Welcome [%s] to home page"%name)
 7 def tv(name):
 8     print("Welcome [%s] to tv page"%name)
 9 def movie(name):
10     print("Welcome [%s] to movie page"%name)
11 tv = login(tv)
12 tv("Young")

结果:

登录验证.

Welcome [Young] to tv page

 

使用装饰器:

 1 def login(func):
 2     def inner(arg):
 3         print("登录验证.")
 4         func(arg)
 5     return inner
 6 
 7 def home(name):
 8     print("Welcome [%s] to home page"%name)
 9 
10 @login  # 程序一执行就相当于执行tv = login(tv)
11 def tv(name):
12     print("Welcome [%s] to tv page"%name)
13 def movie(name):
14     print("Welcome [%s] to movie page"%name)
15 #tv = login(tv)#相当于@login
16 tv("Young")

 

 

返回值

 1 def login(func):
 2     def inner(*args,**kwagrs):
 3         print("登录验证.")
 4         return func(*args,**kwagrs)
 5     return inner
 6 
 7 def home(name):
 8     print("Welcome [%s] to home page"%name)
 9 
10 @login  # 程序一执行就相当于执行tv = login(tv)
11 def tv(name,passwd=123):
12     print("Welcome [%s] to tv page"%name)
13     return 4
14 @login
15 def movie(name):
16     print("Welcome [%s] to movie page"%name)
17 #tv = login(tv)#相当于@login
18 ret = tv("Young",passwd=123)
19 print(ret)
20 movie("Young")

 

以下部分一是对上述内容中装饰器的解释和补充,另一个视为下面的复杂应用做铺垫。

1 def w1(main_func):
2     def outer(request,kargs):
3         print('before')
4         main_func(request,kargs)
5         print('after')
6     return outer
7 @w1
8 def show():
9     pass

解析:

首先开始执行@w1,然后执行def  w1(main_func):

对于def  w1(main_func): 主要包括两部分内容 def outer(request,kargs):  return outer 两个部分,对于def outer(request,kargs): 只是函数定义,没有调用,所以不会执行函数内容;然后执行return outer 返回outer。然后show函数被重新定义,即w1(show)的返回值outer = show

 

以下内容详细看看(作为理解即可,很多时候用不到):

 1 def Filter(before_func,after_func):
 2     def outer(main_func):
 3         def wrapper(request,kargs):
 4             before_func(request,kargs)
 5             main_func(request,kargs)
 6             after_func(request,kargs)
 7         return wrapper
 8     return outer
 9 
10 @Filter(before,after)
11 def Index(request,kargs):
12     print('Index') 
  1.  执行Filter(before,after),注意是Filter而不是@,而Filter()的内容是def outer()return outer(注:这里outer并没有被调用,所以函数的内容并没有执行)
  2.  因为1  的返回值是outer ,所以开始执行@outer@outerindex作为参数,开始执行到def  outer()(但是wrapper函数内容并没有执行),接下来执行return wrapper ,即返回值是wrapper
  3. 此时新的Insex = wrapper   最后执行的Index=新Index

 

posted @ 2016-08-28 21:06  雨纷纷草木深  阅读(291)  评论(0编辑  收藏  举报