生成器+列表生成式,生成器可以节省内存,随时调取函数运行,以及实现多线程运行函数,__next__()和.send(参数)的区别,a,b=b,a+b其实是元祖的用法,出现异常状态用try...except StopIteration来处理

列表生成式:是代码更简洁.

生成器+列表生成式,生成器可以节省内存,随时调取函数运行,以及实现多线程运行函数,__next__()和.send(参数)的区别,a,b=b,a+b其实是元祖的用法,出现异常状态用try...except StopIteration来处理

生成器+列表生成式,生成器可以节省内存,随时调取函数运行,以及实现多线程运行函数,__next__()和.send(参数)的区别,a,b=b,a+b其实是元祖的用法,出现异常状态用try...except StopIteration来处理也可以是函数,比如func(i)

生成器:generator

生成器+列表生成式,生成器可以节省内存,随时调取函数运行,以及实现多线程运行函数,__next__()和.send(参数)的区别,a,b=b,a+b其实是元祖的用法,出现异常状态用try...except StopIteration来处理

列表生成式,是中括号,改成小括号,就是生成器:

生成器+列表生成式,生成器可以节省内存,随时调取函数运行,以及实现多线程运行函数,__next__()和.send(参数)的区别,a,b=b,a+b其实是元祖的用法,出现异常状态用try...except StopIteration来处理

如果你用列表生成式,生成一亿个数据:这里会卡好久,会生成一亿个数据到内存里去。

生成器+列表生成式,生成器可以节省内存,随时调取函数运行,以及实现多线程运行函数,__next__()和.send(参数)的区别,a,b=b,a+b其实是元祖的用法,出现异常状态用try...except StopIteration来处理

而用生成器,立马会得到生成器的内存地址,不需要等待:

生成器+列表生成式,生成器可以节省内存,随时调取函数运行,以及实现多线程运行函数,__next__()和.send(参数)的区别,a,b=b,a+b其实是元祖的用法,出现异常状态用try...except StopIteration来处理

但是要注意,生成器c不允许使用下标的方式,进行取值。因为循环还没计算到这个值。

生成器+列表生成式,生成器可以节省内存,随时调取函数运行,以及实现多线程运行函数,__next__()和.send(参数)的区别,a,b=b,a+b其实是元祖的用法,出现异常状态用try...except StopIteration来处理

  • 生成器只有在调用时才会生成相应的数据;
  • 生成器有一种方法c.__next__(),来取下一个值,只有下一个next,没办法返回上一个值。它每次只保留一个值;
  • 只记录当前位置;
  • 只有一个方法__next__()方法。在py2里,生成器的下一个方法的写法是next()

生成器+列表生成式,生成器可以节省内存,随时调取函数运行,以及实现多线程运行函数,__next__()和.send(参数)的区别,a,b=b,a+b其实是元祖的用法,出现异常状态用try...except StopIteration来处理

现在我们用另外一种方法来创建一个生成器:

生成器+列表生成式,生成器可以节省内存,随时调取函数运行,以及实现多线程运行函数,__next__()和.send(参数)的区别,a,b=b,a+b其实是元祖的用法,出现异常状态用try...except StopIteration来处理

fib(10)代表max生成10个数列,a代表第一个值,b代表第二个值,n表示循环10次

生成器+列表生成式,生成器可以节省内存,随时调取函数运行,以及实现多线程运行函数,__next__()和.send(参数)的区别,a,b=b,a+b其实是元祖的用法,出现异常状态用try...except StopIteration来处理

生成器+列表生成式,生成器可以节省内存,随时调取函数运行,以及实现多线程运行函数,__next__()和.send(参数)的区别,a,b=b,a+b其实是元祖的用法,出现异常状态用try...except StopIteration来处理这里很容易混淆,大家一定要注意!!!

结果如下:

生成器+列表生成式,生成器可以节省内存,随时调取函数运行,以及实现多线程运行函数,__next__()和.send(参数)的区别,a,b=b,a+b其实是元祖的用法,出现异常状态用try...except StopIteration来处理

这个时候,我们把print(b)替换为yield b,yield是产量的意思,这个时候,这个fib()就是生成器了

yield的作用,就是中断状态,就是返回当前状态的值,并且函数停在这个位置。yield在第一次next的时候,函数执行到yield就返回,(yield之前的程序执行完,yield后面的就不执行了!),紧接着第二次next的时候,首先,函数会继续执行yield后面的程序,然后继续执行循环,直至执行到yield之前的函数!!!如此反复。

而且。这个fib(100)这个生成器非常牛逼,可以用f.__netxt__()的方式,随时调用函数fib(),随时执行,调用一次以后可以去干别的时候,回头再来执行一次。这个就是生成器的牛逼之处!!!

生成器+列表生成式,生成器可以节省内存,随时调取函数运行,以及实现多线程运行函数,__next__()和.send(参数)的区别,a,b=b,a+b其实是元祖的用法,出现异常状态用try...except StopIteration来处理

生成器+列表生成式,生成器可以节省内存,随时调取函数运行,以及实现多线程运行函数,__next__()和.send(参数)的区别,a,b=b,a+b其实是元祖的用法,出现异常状态用try...except StopIteration来处理

生成器+列表生成式,生成器可以节省内存,随时调取函数运行,以及实现多线程运行函数,__next__()和.send(参数)的区别,a,b=b,a+b其实是元祖的用法,出现异常状态用try...except StopIteration来处理

生成器+列表生成式,生成器可以节省内存,随时调取函数运行,以及实现多线程运行函数,__next__()和.send(参数)的区别,a,b=b,a+b其实是元祖的用法,出现异常状态用try...except StopIteration来处理

生成器+列表生成式,生成器可以节省内存,随时调取函数运行,以及实现多线程运行函数,__next__()和.send(参数)的区别,a,b=b,a+b其实是元祖的用法,出现异常状态用try...except StopIteration来处理

如果你不用for循环,一直用__next__()方法,就会超过数值,这个时候会报错,出一个异常代码StopIteration:done

生成器+列表生成式,生成器可以节省内存,随时调取函数运行,以及实现多线程运行函数,__next__()和.send(参数)的区别,a,b=b,a+b其实是元祖的用法,出现异常状态用try...except StopIteration来处理

注意函数里的return '---done---',那么在报错的打印中就也会返回这个return这个字符串:

return在这里的作用就是异常的时候打印的东西。

生成器+列表生成式,生成器可以节省内存,随时调取函数运行,以及实现多线程运行函数,__next__()和.send(参数)的区别,a,b=b,a+b其实是元祖的用法,出现异常状态用try...except StopIteration来处理

我们现在要对异常做处理:我们要抓住异常状态用try...except StopIteration来处理

只要出的错误是StopIteration,那么下面的代码就可以抓住,然后做相应的处理:

在 try里用next(生成器)的写法跟__next__()方法是一样的效果。

生成器+列表生成式,生成器可以节省内存,随时调取函数运行,以及实现多线程运行函数,__next__()和.send(参数)的区别,a,b=b,a+b其实是元祖的用法,出现异常状态用try...except StopIteration来处理

生成器+列表生成式,生成器可以节省内存,随时调取函数运行,以及实现多线程运行函数,__next__()和.send(参数)的区别,a,b=b,a+b其实是元祖的用法,出现异常状态用try...except StopIteration来处理

生成器+列表生成式,生成器可以节省内存,随时调取函数运行,以及实现多线程运行函数,__next__()和.send(参数)的区别,a,b=b,a+b其实是元祖的用法,出现异常状态用try...except StopIteration来处理

生成器还有一个牛逼的用法,实现多线程的并行效果:

这个是一个典型的生产者消费者模型,一个人生产包子,一个吃包子:

首先我们牢记,yield的作用,就是中断状态,就是返回当前状态的值,并且函数停在这个位置。yield在第一次next的时候,函数执行到yield就返回,(yield之前的程序执行完,yield后面的就不执行了!),紧接着第二次next的时候,首先,函数会继续执行yield后面的程序,然后继续执行循环,直至执行到yield之前的函数!!!如此反复。

生成器+列表生成式,生成器可以节省内存,随时调取函数运行,以及实现多线程运行函数,__next__()和.send(参数)的区别,a,b=b,a+b其实是元祖的用法,出现异常状态用try...except StopIteration来处理

生成器+列表生成式,生成器可以节省内存,随时调取函数运行,以及实现多线程运行函数,__next__()和.send(参数)的区别,a,b=b,a+b其实是元祖的用法,出现异常状态用try...except StopIteration来处理

生成器+列表生成式,生成器可以节省内存,随时调取函数运行,以及实现多线程运行函数,__next__()和.send(参数)的区别,a,b=b,a+b其实是元祖的用法,出现异常状态用try...except StopIteration来处理

我们这里发现用__next__()不会给yield传值,但是send(变量)可以相当于是__next__(),而且给yield传值了!

生成器+列表生成式,生成器可以节省内存,随时调取函数运行,以及实现多线程运行函数,__next__()和.send(参数)的区别,a,b=b,a+b其实是元祖的用法,出现异常状态用try...except StopIteration来处理

我们再看生产者的代码:

生成器+列表生成式,生成器可以节省内存,随时调取函数运行,以及实现多线程运行函数,__next__()和.send(参数)的区别,a,b=b,a+b其实是元祖的用法,出现异常状态用try...except StopIteration来处理

生成器+列表生成式,生成器可以节省内存,随时调取函数运行,以及实现多线程运行函数,__next__()和.send(参数)的区别,a,b=b,a+b其实是元祖的用法,出现异常状态用try...except StopIteration来处理

生成器+列表生成式,生成器可以节省内存,随时调取函数运行,以及实现多线程运行函数,__next__()和.send(参数)的区别,a,b=b,a+b其实是元祖的用法,出现异常状态用try...except StopIteration来处理

上面的这个方法也叫异步,也叫协程,nginx用的也是这个方法

上一篇:「JoyOI1080」N皇后


下一篇:cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第七步---英雄要升级&属性--解析csv配置文件