2011-06-12 51 views
4

我有两个发电机。首先发电机有时需要调用第二发电机产生回从那里得到的值:打包/解包发电机

def a(): 
    for _b in b(): 
     yield _b 

def b(): 
    yield 1 
    yield 2 

for _a in a(): 
    print _a 

有没有更优雅的方式来做到这一点:

for _b in b(): 
    yield _b 

我已经试过这样:

yield *b() 

但肯定它不起作用。我有Python 2.6。

+1

你实际上是否试图从'b()'一次返回(yield)一切? – 2011-06-12 14:31:56

+0

是的,我试图在()来产生我从b()获得的所有值。 – warvariuc 2011-06-12 15:43:36

+0

'a()'是scrapy蜘蛛的回调函数(http://doc.scrapy.org/topics/spiders.html#topics-spiders) – warvariuc 2011-06-12 15:58:10

回答

6

我想你的意思是PEP380。这是available from Python 3.3。它看起来像:

yield from b() 

在Python2中没有特殊的语法。你只需要使用for循环。

您的问题中的a函数实际上完全没用。你可以在它的地方使用b

+0

在真正的代码(scrapy蜘蛛法)'a'产生它自己的一些价值。我想如果有PEP,这意味着问题是已知的,目前还没有优雅的解决方案。 – warvariuc 2011-06-12 15:51:23

2

那么,在这个简单的例子中,你可以只写a = ba = lambda: b。但是,如果a添加了自己的元素,你可以使用itertools.chain

import itertools 
def a(): 
    return itertools.chain(['a-value'], b()) 

记住,虽然这种变异可能更短,for: yield是一个相当直观的(因此很容易理解)模式。

+1

感谢您的选择,虽然不是优雅 – warvariuc 2011-06-12 15:52:54

3

您可以使用生成器表达式。它和循环一样简洁,加上它表明你的代码主要是为了产生一个返回值而不是副作用。

def a(): 
    return (_b for _b in b()) 

正如phihag说,你也许可以简单地写a = b如果你的代码是真的很喜欢这个例子中,由于A和B返回相同的序列。

+1

你写的'a'是一个叫做'iter'的内建函数' – 2011-06-12 14:59:51

+0

'返回(_b for _b in b())'更容易(和有效)写成'return b()',并且它不起作用if 'a'本身就是一个生成器函数(如问题所述)。 – 2011-06-12 15:01:07

+0

是的,这是行不通的,因为它产生的值类型为 warvariuc 2011-06-12 15:49:23