2013-02-08 77 views
1

最近我發現使用下面的語句在我的一些功能自己:返回,如果值成語(有條件返回)

[...] 
def validate(self): 
    # Possibly do something "expensive" to calculate whether data is valid or not 
    if data_is_valid: 
     return ObjectOfSomeSort(validated_data) 
    return False 

ret = self.validate() 
if ret: 
    return ret 
[...] 

我覺得像ret = ...; if ret: return ret語法有點笨拙,unpythonic,但是,而我並不總是能夠做到像

if self.validate(): 
    return self.validate() 

東西,因爲偶爾我的驗證函數包含一些比較昂貴的計算邏輯。

所以,StackOverflow,這種問題存在什麼樣的python習語;具體而言,我還能如何「有條件地返回」?

+0

我必須同意,是完全unpythonic,因爲我實際上沒有得到你想做什麼......如果它很難解釋,這是一個壞主意:P – KurzedMetal 2013-02-08 15:38:54

+0

我的「驗證」函數返回False如果數據無效。如果數據是有效的,我想早日退出調用函數(調用self.validate()的函數);如果不是,我想繼續執行流程。 – 2013-02-08 15:40:41

+0

嗯,看起來這裏的語義有點不對:'self.validate()'意味着你要確保* current(!)*對象,又名'self'是有效的。 – 2013-02-08 15:41:37

回答

1

你可以做

def ifloop(x): 
    if x: yield x 

for ret in ifloop(self.validate()): 
    return ret 
+0

我想我會採取如果塊首先;-)。但有趣的是巧妙地使用發電機功能。 – mgilson 2013-02-08 15:39:36

+0

+1爲聰明的發電機;這些都是我正在尋找的答案;) – 2013-02-08 15:41:54

+2

這是運行時的'NameError'。 – Bakuriu 2013-02-08 15:43:49

2

地道的Python是使用一個例外。

class InvalidDataError(Exception): 
     pass 

    def get_valid_object(): 
     if not data_is_valid: 
      raise InvalidDataError() 
     return ObjectOfSomeSort(validated_data) 

然後使用它:

try: 
    valid_object = get_valid_object() 
except InvalidDataError: 
    ... handle error 
+1

一個例外是我完全忘記的;謝謝! – 2013-02-08 15:43:41

0

如果代碼不需要你if後繼續,我會寫:

return self.validate() or None 
+0

我喜歡這樣,即使非python程序可能會感到困惑。 – Bakuriu 2013-02-08 15:46:46

+0

這將返回自我。如果self.validate()爲非True,則返回None;我希望非True情況繼續執行(即從不觸發return語句) – 2013-02-08 15:47:06

0

您可以使用NULL object pattern ,確保添加以下方法,因此它的實例也將被視爲False - 這將使測試更容易:

def __nonzero__(self) : 
    return False 

這樣Null對象的用處在於它們可以像幾乎任何其他對象使用,因此在很多情況下,你就不會在你的代碼的其餘部分,可以假定它來檢查他們自己拿到的有效對象一些其他類型。

我第一次聽到Alex Martelli在Python Cookbook的第二版中的這種模式。這是配方6.17