2011-02-22 60 views
3

例如,這些在operator module被定義,並且可以被用作這樣的:在Python中,boolean'和','或'的操作符方法是什麼?

import operator 
print operator.__add__ # alias add -> + 
print operator.__sub__ # alias sub -> - 
print operator.__and__ # alias and_ -> & 
print operator.__or__ # alias or_ -> | 

那麼什麼是andor等效?

print operator."and ?????" # should be boolean-and 
print operator."or ????" # should be boolean-or 
+1

問題是什麼? '和'和'或'必須是特殊的,因爲它們會短路。 – 2011-02-22 22:14:13

+0

如果您不希望函數等效(即短路),只需使用lambda。 – 2011-02-22 22:14:59

+4

這*是一個真正的問題,即使沒有真正寫清楚。 – 2011-02-22 22:16:35

回答

6

這些不存在。你能做的最好是用lambda來替換它們:

band = (lambda x,y: x and y) 
bor = (lambda x,y: x or y) 

的原因是你無法實現的and完整的行爲或or因爲他們可以短路。

E.G:

if variable or long_fonction_to_execute(): 
    # do stuff 

如果variableTrue,該long_fonction_to_execute將永遠不會被調用,因爲Python知道比or必須返回True反正。這是一個優化。大多數時候這是一個非常理想的功能,因爲它可以節省大量無用的處理。

但它意味着你不能讓一個函數:

E.G:

if bor(variable, long_fonction_to_execute()): 
    # do stuff 

在這種情況下,long_fonction_to_execute甚至被評估之前調用。

幸運的是,由於您使用了生成器和列表解析功能,您很少需要類似的東西。

+2

那些當然不會短路。 – 2011-02-22 22:20:30

12

andor運營商沒有操作模塊中的等價物,因爲它們不能作爲一個功能來實現。這是因爲它們是短路的:它們可能不會根據第一操作數的結果來評估它們的第二操作數。

+0

他們缺席的好理由 – ide 2011-02-22 22:15:20

3

擴展電子SATIS的回答:

lazyand = (lambda x,y: x() and y()) 
lazyor = (lambda x,y: x() or y()) 

這裏的區別是在通過條件本身的thunk(形式的函數「() - >值」),它們只計算如所須。 (可以認爲只有y需要進行懶惰評估,但爲了保持一致,我這樣寫)。

也就是說,這保留了and(和or)的「懶惰」方面,代價是更詳細的代碼和更多的對象/方法調用。

andexpr = lazyand(lambda: false, lambda: never_executed()) 
andexpr() # false 

我將很難真正建議使用這種方法雖然 - 請注意,這些的thunk必須明確,如上圖所示是很重要的。這可能是它未包含在operator模塊中的原因之一。其他一些語言允許通過名稱或隱含的「提升」。

快樂編碼。

+1

非常好,+1。但是,當然意味着這些參數是可調用的,所以這對於一個屬性,一個惰性的gettext翻譯的字符串或一個ORM查詢集都不起作用。總之,在某些特殊情況下,它可能是一個很好的替代方案 – 2011-07-13 14:32:54

相關問題