这可能是一个更好的例子:
class GeneratorsSample(object):
def DoReturn(self):
counter, maxCounter = 0, 5
listResults = []
while counter < maxCounter:
print "tic"
listResults.append(counter*2)
counter += 1
return listResults
def DoYield(self):
counter, maxCounter = 0, 5
while counter < maxCounter:
print "tic"
yield counter*2
counter += 1
return
generatorSample = GeneratorsSample()
ret = generatorSample.DoReturn()
yld = generatorSample.DoYield()
for r in ret: print "toc", r
for r in yld: print "toc", r
print ret
print yld
首先看看这些行:
for r in ret: print "toc", r
for r in yld: print "toc", r
产生相同的数值,但在“回归”的版本,抽动所有放在第一位,那么所有的TOC的。在“良率”版本中,抽搐和toc是散布的。
但是这两种方法之间的主要差异是由这些线所示:
print ret # prints: [0, 2, 4, 6, 8]
print yld # prints: <generator object DoYield at 0x0000000002202630>
这里,ret
是所产生的所有的值的列表。也就是说,当这项任务是由:产生
ret = generatorSample.DoReturn()
完整列表然后,并返回的完整列表。
随着发生器的方法,整个列表不是生成的,事实上,没有元素的计算。只需提及一台发电机,根据需要即可生成元件“只有苍蝇”。
换句话说,“返回”的方法:
generates a number
generates a number
generates a number
...
uses that number
uses that number
uses that number
...
而产生办法:
generates a number
uses that number
generates a number
uses that number
...
发电机的效率是一个事实,即他们只花时间生成单一元素,因为他们需要(如果他们需要)。如果maxCounter
比方说是100万,并且计算比counter * 2
更复杂,那么获得第一个输出所花费的时间会有明显的改善。
事实上,你可以看到,通过添加人工延迟(这里,与time.sleep(1)
:
import time
class GeneratorsSample(object):
def DoReturn(self):
counter, maxCounter = 0, 5
listResults = []
while counter < maxCounter:
v = counter * 2
time.sleep(1)
print "[DoReturn] computed %d" % v
listResults.append(v)
counter += 1
return listResults
def DoYield(self):
counter, maxCounter = 0, 5
while counter < maxCounter:
v = counter * 2
time.sleep(1)
print "[DoYield] computed %d" % v
yield counter*2
counter += 1
return
generatorSample = GeneratorsSample()
ret = generatorSample.DoReturn()
yld = generatorSample.DoYield()
for r in ret: print "[return loop] using", r
print("")
for r in yld: print "[yield loop] using", r
输出是:
[DoReturn] computed 0
[DoReturn] computed 2
[DoReturn] computed 4
[DoReturn] computed 6
[DoReturn] computed 8
[return loop] using 0
[return loop] using 2
[return loop] using 4
[return loop] using 6
[return loop] using 8
[DoYield] computed 0
[yield loop] using 0
[DoYield] computed 2
[yield loop] using 2
[DoYield] computed 4
[yield loop] using 4
[DoYield] computed 6
[yield loop] using 6
[DoYield] computed 8
[yield loop] using 8
您正在构建的发电机内的名单,但你(可能)*只是*想要产生值,相反,当你建立它时会产生列表,导致不同。例如,在'DoYield()'中你根本不需要'listResults',你应该只是'产量计数器* 2'直接。 – 2014-10-01 23:17:42
@TomDalton谢谢。和你的意思。但是,我期待'DoYield()'运行的结果是'tic [0]''tic [0,2]'tic [0,2,4]'等等,然后是'toc [0] ''toc [0,2]'等等。我不明白为什么'toc'打印在'tic'语句之间。 – user131983 2014-10-01 23:37:23
@ user131983考虑在我的答案底部运行代码,看看是否有助于解释为什么'toc'打印在'tic'语句之间 – jedwards 2014-10-01 23:52:02