2015-03-02 27 views
4

我很喜歡有以下行爲:在python中混合yield和return語句是不是很好的做法?

def foo(bar=None): 
    if bar: 
     return other_function(other_thing[bar]) 
    else: 
     for i in other_thing: 
      yield other_function(i) 

的想法是,該功能可以被用來作爲發電機來構建所有實例,也可用於返回特定的實例。這是一個在Python中做到這一點的好方法嗎?如果沒有,是否有更好的方法。

+0

我認爲這隻適用於Python 3 – warvariuc 2015-03-02 09:43:51

+0

...甚至在Python 3中,它並不意味着你期望的。 – bereal 2015-03-02 09:48:10

+0

你可以讓它返回一個值或一個可迭代的值(例如,調用另一個生成器函數的結果),但是由於不一致,這似乎是一個可怕的想法。 – interjay 2015-03-02 09:57:30

回答

6

只有在Python 3它在語法上可以具有在同一個函數return valueyield,在Python 2將導致:

SyntaxError: 'return' with argument inside generator 

在Python 3 return value內的發電機實際上是一個語法糖raise StopIteration(value),這也是由yield from條款支持:

def f(): 
    yield from iter('123') 
    return 'ok' 

def g(): 
    message = yield from f() 
    print('Message:', message) 

In [1]: list(g) 
Message: ok 
Out[1]: ['1', '2', '3'] 

所以,這個結構不會做你希望它是什麼。此外,根據參數值來改變函數的返回類型(或者說,接口)似乎並不是一個很好的(「pythonic」)想法。這可能是口味的問題,不過,這裏是吉多·範羅蘇姆說,在他的書中Masterminds of Programming採訪:

我有一些個人的眼中釘:首先,這是專門針對動態語言,不要使方法的返回類型取決於其中一個參數的值;否則,如果你不知道關係,可能很難理解返回的結果 - 也許類型決定參數是從一個變量中傳入的,該變量的內容在閱讀代碼時不容易猜到。

+0

你能否澄清你最後一句話?這是一個很好的答案,但爲什麼不呢? – 2015-03-02 09:59:55

+0

@DavidBoshton我已經更新了答案。基本上,這會帶來更少的驚喜,並使代碼在未來更易於理解。當然,如果你知道你在做什麼,沒有規則沒有例外。 – bereal 2015-03-02 10:10:47

+0

這也是[明確記錄](https://docs.python.org/3/reference/expressions.html#yield-expressions):*在函數體中使用yield表達式會使該函數成爲一個生成器*。超越這一點並不重要。你使用'yield',它是一個生成器函數,結束了。可達性在這裏不起作用。 – 2018-01-02 10:39:57

相關問題