2009-05-04 57 views
5

我在https://storm.canonical.com/Tutorial閱讀風暴ORM的教程,我偶然發現了下面的一段代碼:這段代碼說明了什麼python特性?


store.find(Person, Person.name == u"Mary Margaret").set(name=u"Mary Maggie") 

我不知道該的第二個參數找到方法進行評估,以真/假。我認爲它會被解釋爲lambda。如果那是真的,我如何才能在我的功能中達到同樣的效果?

回答

0

因爲我是一個Java程序員...我猜... 它是運算符重載? Person.name ==是一個操作符重載,與其做比較......它會產生一個SQL查詢

我的0.02 $

+0

Java和運算符重載...不認爲它會實現。另一方面,也許你是對的。 – Geo 2009-05-04 20:30:11

+10

奇怪......當另一個回答基於Storm中的實際源代碼時,接受「猜測」答案。 – 2009-05-04 20:49:32

+0

對不起,但我的猜測「足夠快」:-) PS你是對的,這很奇怪! – dfa 2009-05-04 22:12:22

1

它看起來並不像一個Python拉姆達給我。我沒有閱讀Storm的代碼,但Miles可能是正確的,因爲它使用了懶惰的評估模式。

要了解關於python lambda函數的更多信息,請閱讀Dive Into Python的出色chapter

22

Person.name有一個重載的__eq__方法,它返回的不是布爾值,而是一個存儲表達式兩邊的對象;可以使用find()方法檢查該對象以獲取將用於過濾的屬性和值。我將其描述爲一種懶惰的評估模式。

在Storm中,它與Comparable object一起實施。

8

魔術出現在Person.name屬性中,這會導致重載__eq__(& c)的類型返回非布爾值。如你所見,Storm的資源可供你在線瀏覽(並很好地模仿;-),正如你所看到的那樣,它們不會點亮「黑魔法」;-)

9

Person.name是一些使用自定義__eq__方法鍵入。雖然__eq__通常會返回一個布爾(ish)值,但它實際上可以返回任何您想要的值,包括lambda。有關此方法和相關方法的更多信息,請參閱Python special method names

可能(尤其是如果你使用其他面向對象的語言如Java)最混亂/誤導性的這部分是Person.nameperson.name(其中personPerson一個實例),不必有任何關係彼此。例如:

class Person(object): 
    name = "name of class" 
    def __init__(self): 
    self.name = "name of instance" 

person = Person() 
print Person.name 
print person.name 

這將打印:

name of class 
name of instance 

注意的是,類屬性正好被設置在類體內,而實例屬性中__init__方法設置。

在你的情況,你會設置Person.name對象與定製__eq__方法返回一個lambda,是這樣的:

class LambdaThingy(object): 
    def __init__(self, attrname): 
    self.__attrname = attrname 

    def __eq__(self, other): 
    return lambda x: getattr(x, self.__attrname) == other 

class Person(object): 
    name = LambdaThingy('name') 

    def __init__(self, name): 
    self.name = name 

equals_fred = Person.name == "Fred" 
equals_barney = Person.name == "Barney" 

fred = Person("Fred") 

print equals_fred(fred) 
print equals_barney(fred) 

此打印:

True 
False 

這當然是避開了「太聰明」的邊緣,所以我在生產代碼中使用它會非常謹慎。明確的lambda可能會對未來的維護者更清晰,即使它稍微冗長一些。