python中generator是什么类型,Python global用法

  python中generator是什么类型,Python global用法

  在介绍yield之前,我们必须先解释一下Python的迭代器(iterator)和生成器(generator)。

  I迭代器(迭代器)。

  在Python中,可以对任何类型的Python使用for循环,包括列表和祖先。实际上,for循环可以用于可重复的对象。这是迭代器。

  迭代器是实现迭代器协议的对象。在Python的迭代器协议中,使用next方法的对象输入下一个结果,并在一系列结果的结尾导致StopIteration。所有这些对象都可以用for循环或其他遍历工具在Python中重复。在迭代工具中,每次迭代都会调用next方法,以确定捕获StopIteration异常的时间和结束时间。

  使用迭代器有一个明显的好处,就是一次只从一个对象读取一个数据不会增加内存开销。

  例如,要逐行读取文件的内容,可以使用readlines()方法,并编写如下代码:

  forlineinopen(test . txt . read lines)):

  打字线

  这是可行的,但不是最好的方法。因为他实际上是一次性将文件加载到内存中并逐行打印。如果文件很大,这种方法的内存开销会很高。

  使用file的迭代器,我们可以写如下。

  forlineinopen(test . txt)):#使用文件迭代器

  打字线

  这是最简单快捷的写作方法。它每次都使用迭代器读取下一行,而不是显式读取文件。

  二。生成器(构造器))

  生成器与Python中迭代器协议的概念相关联。简单来说,包含yield语句的函数是专门编译到生成器中的。调用该函数时,将返回支持迭代器接口的生成器对象。函数可能包含return语句,但它的作用是yield用来生成值。

  与普通函数不同,它生成值并退出。生成器生成值后会自动挂起,挂起执行和状态。变量在本地保存状态信息,并在函数恢复时重新启用。

  定义(n):forIinrange(n):产量i **2。

  锻造(5):打印I,:。

  0 : 1 : 4 : 9 : 16 :

  要了解他是如何工作的,请尝试下一种方法:

  t=g(5)).

  t.next())

  0

  t.next())

  一个

  t.next())

  四

  t.next())

  九

  t.next())

  16

  t.next())

  跟踪(mostrecentcalllast):

  文件中的第1行

  停止解释

  执行next五次后,生成器抛出StopIteration异常,迭代结束。

  我们来看收益率的例子。用生成器生成斐波那契数列。

  deffab(最大) :

  a,b=0,1

  而最大:

  产生

  a,b=b,a b

  forIinfab(20):打印I,,。

  0、1、1、2、3、5、8、13、

  看完这里就能理解发电机的抽象概念了~ ~。

  三。补充

  yield关键字用于定义生成器。它的具体作用是用它作为返回,从一个函数返回一个值,但不同的是,用yield返回后,可以从用yield返回的最后一个位置继续执行函数。即yield会返回一个函数,将返回值传递给调用者,然后“瞬移”回来,继续运行函数,直到yield语句再次返回新值。

  使用yield返回时,调用者实际上获得的是迭代器对象。迭代器的值就是返回值。另外,当迭代器的next))方法被调用时,函数会继续还原yield语句的执行环境,直到遇到下一个yield。如果遇到yield,它将抛出一个异常来指示迭代的结束。

  请看下面的例子:

  def test _ yield(:…yield 1…yield 2…yield)1,2 ) a=test_yie

  LD()a . next()1a . next()2a . next()(1,2) a.next()Traceback(最近一次调用last): File ,第1行,in?停止迭代

  1.包含产量的函数

  如果你看到一个函数包含yield,说明这个函数已经是一个生成器了,它的执行会和其他普通函数有很大不同。例如,下面的简单函数:

  defh():

  打印“勇敢”

  产量5

  h()

  可以看到,调用h()后,print语句并没有执行!这就是屈服。那么,如何执行print语句呢?这是后面要讨论的问题。通过后面的讨论和学习,我们会了解yield的工作原理。

  2.屈服是一种表达

  在Python2.5之前,Python yield是一个语句,而现在在2.5中,yield是一个表达式,比如:

  m=产量5

  表达式的返回值(yield 5)会赋给M,所以认为m=5是错误的。那么如何得到(收益率5)的返回值呢?您需要使用稍后介绍的send(msg)方法。

  3.通过下面的()语句看原理

  现在,让我们来揭示yield是如何工作的。我们知道上面我们的h()在被调用后并没有被执行,因为它有一个yield表达式。因此,我们让它通过next()语句执行。next()语句将继续执行生成器,直到下一个yield表达式。例如:

  defh():

  打印“汶川”

  产量5

  打印战斗!

  c=h()

  下一个

  调用后,h()开始执行,直到遇到yield 5,所以输出结果是:

  汶川

  当我们再次调用c.next()时,我们将继续执行,直到找到下一个yield表达式。因为它背后没有Python屈服,所以会抛出一个异常:

  汶川

  打架!

  回溯(mostrecentcalllast):

  文件/home/evergreen/Codes/yildd . py ,第11行,在

  c .下一个()

  停止迭代

  4.发送(消息)和下一步()

  了解了next()如何让包含yield的函数执行之后,我们再来看另一个非常重要的函数,send(msg)。其实next()和send()在某种意义上有类似的功能。区别在于send()可以传入yield表达式的值,而next()不能传入具体的值,只能传一个。所以我们可以看到c.next()和c.send(None)的功能是一样的。看看这个例子:

  defh():

  打印汶川,

  m=yield5 #战斗!

  printm

  d=产量12

  打印“我们在一起”!

  c=h()

  C.next()#等效于c.send(None)

  c . send(‘战斗!’)#(yield5)表情给出的是‘打架!’输出结果是:

  文传格斗!

  需要提醒的是,第一次调用时,请使用next()语句或send(None)。不能使用send发送None以外的值,否则会得到错误,因为没有Python yield语句接收这个值。

  5.send (msg)和next()的返回值

  Send(msg)和next()有返回值。它们的返回值是特殊的,它们返回下一个yield表达式的参数。如收益率为5,则返回5。你在这里学到了什么吗?在本文的第一个例子中,在list中遍历生成器实际上调用了一个list。每次都是Next(),以及list的返回值。每次的Next()都是yield的参数,也就是我们开始认为的东西被推了进去。让我们继续上面的例子:

  defh():

  打印汶川,

  m=yield5 #战斗!

  printm

  d=产量12

  打印“我们在一起”!

  c=h()

  M=c.next()#m获取yield5的参数值5。

  d=c.send(战斗!)#d获得yield12的参数值12。

  打印我们永远不会忘记,m, ,d输出结果:

  文传格斗!

  我们永远不会忘记5.12日

  6.throw()和close()中断生成器

  中断发电机是一种非常灵活的技术。您可以通过抛出GeneratorExit异常来终止生成器。Close()方法的功能是一样的,其实在内部它调用throw(GeneratorExit)。让我们看看:

  defclose(自身):

  尝试:

  self.throw(GeneratorExit)

  except(GeneratorExit,StopIteration):

  及格

  否则:

  raiseRuntimeError( generatoringoredgerenatorexit )

  # Otherexceptionsarenotcaught

  因此,当我们调用close()方法,然后调用next()或send(msg)时,将会引发一个异常:

  回溯(mostrecentcalllast):

  文件/home/evergreen/Codes/yildd . py ,第14行,在

  d=c.send(战斗!)#d获得yield12的参数值12。

  停止迭代

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: