2011-06-12 28 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