2009-05-04 12 views
5

Ich las Tutorial Storm ORM bei https://storm.canonical.com/Tutorial, und ich auf das folgende Stück Code gestolpert:Welche Python-Funktion wird in diesem Code dargestellt?


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

Ich bin nicht sicher, dass das zweite Argument der Methode True/False ausgewertet werden können. Ich denke, es wird als Lambda interpretiert. Wenn das stimmt, wie kann ich den gleichen Effekt in meinen Funktionen erreichen?

Antwort

0

seit ich ein Java-Programmierer bin ... Ich schätze ... ist es Operator überladen? Person.name == ist ein Operator überlastet, dass anstelle Vergleich zu tun ... es erzeugt eine SQL-Abfrage

meine 0,02 $

+0

Java und Operator überladen ... glaube nicht, dass es jemals wahr werden wird. Auf der anderen Seite hast du vielleicht recht. – Geo

+10

Ungerade .... Akzeptieren einer "raten" Antwort, wenn eine andere Antwort auf dem tatsächlichen Quellcode in Storm basiert. –

+0

Entschuldigung, aber meine Vermutung war "schnell genug" :-) PS du hast recht, es ist sehr merkwürdig! – dfa

1

Es sieht nicht wie ein Python Lambda mir. Ich habe den Code für Storm nicht gelesen, aber Miles hat wahrscheinlich Recht damit, dass er ein faules Evaluierungsschema verwendet.

Um mehr über Python Lambda Funktionen zu erfahren, lesen Sie die ausgezeichnete chapter von Dive Into Python.

+0

Ich dachte immer, dass Lambda-Funktionen mit dem Lambda-Schlüsselwort vorangestellt werden müssten, also könnte das nicht der Fall sein, oder? – Geo

22

Person.name hat eine überladene __eq__ Methode, die keinen booleschen Wert zurückgibt, sondern ein Objekt, das beide Seiten des Ausdrucks speichert; Dieses Objekt kann mit der Methode find() untersucht werden, um das Attribut und den Wert zu erhalten, die für die Filterung verwendet werden. Ich würde dies als eine Art faules Bewertungsmuster beschreiben.

In Storm ist es mit der Comparable object implementiert.

8

Die Magie ist in der Person.name Eigenschaft, die zu einem Typ führt, der __eq__ (& c) überlädt, um non-bools zurückzugeben. Storm Quellen sind online für Sie zu durchsuchen (und VORSICHTIG imitieren ;-) unter http://bazaar.launchpad.net/~storm/storm/trunk/files/head%3A/storm/ - wie Sie sehen werden, gehen sie nicht auf die "schwarze Magie" ;-)

9

Person.name ist eine Instanz von einigen Geben Sie eine benutzerdefinierte __eq__ Methode ein. Während __eq__ normalerweise einen booleschen Wert (ish) zurückgibt, kann es tatsächlich zurückgeben, was auch immer Sie wollen, einschließlich eines Lambda. Weitere Informationen zu dieser und verwandten Methoden finden Sie unter Python special method names.

Der wohl verwirrend/irreführende Teil davon (vor allem, wenn Sie zu anderen OO-Sprachen wie Java gewohnt sind), ist, dass Person.name und person.name (wo person ist eine Instanz Person) keine Beziehung haben müssen zu gegenseitig. Zum Beispiel:

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

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

Dies drucken:

name of class 
name of instance 

Beachten Sie, dass die Klasse Eigenschaft nur in der Klasse Körper festgelegt ist, während die Instanz Eigenschaft im __init__ Verfahren eingestellt wird.Dies ist sicherlich

True 
False 

:

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) 

Diese Drucke

: liefert

In Ihrem Fall würden Sie Person.name auf das Objekt mit den benutzerdefinierten __eq__ Verfahren, das auch ein Lambda, so etwas wie diese "Ich bin zu schlau", deshalb wäre ich sehr vorsichtig, wenn es darum geht, dies im Produktionscode zu verwenden. Ein explizites Lambda würde zukünftigen Betreuern wahrscheinlich viel klarer sein, auch wenn es ein wenig ausführlicher ist.

+0

+1 für die großartige Erklärung des "zu cleveren" Teils! – lothar

Verwandte Themen