Domanda

Ho letto il tutorial di Storm ORM su https://storm.canonical.com/Tutorial e Mi sono imbattuto nel seguente codice:


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

Non sono sicuro che il secondo argomento del metodo trova verrà valutato su Vero / Falso. Penso che sarà interpretato come un lambda. Se questo è vero, come posso ottenere lo stesso effetto nelle mie funzioni?

È stato utile?

Soluzione

dal momento che sono un programmatore Java ... sto indovinando ... è un sovraccarico dell'operatore? Person.name == è un operatore sovraccarico che invece fa un confronto ... produce una query SQL

i miei 0,02 $

Altri suggerimenti

Person.name ha un metodo __eq__ sovraccarico che restituisce non un valore booleano ma un oggetto che memorizza entrambi i lati dell'espressione; quell'oggetto può essere esaminato con il metodo find () per ottenere l'attributo e il valore che utilizzerà per il filtro. Lo descriverei come un tipo di modello di valutazione pigro.

In Storm, è implementato con Comparable object .

Person.name è un'istanza di qualche tipo con un metodo __eq__ personalizzato. Mentre __eq__ normalmente restituisce un valore booleano (ish), in realtà può restituire quello che vuoi, incluso un lambda. Vedi Nomi di metodi speciali Python per ulteriori informazioni su questo e sui metodi correlati .

Probabilmente la parte più confusa / fuorviante di questo (specialmente se sei abituato ad altre lingue OO come Java) è che Person.name e person.name ( dove person è un'istanza di Person ) non devono avere relazioni reciproche. Ad esempio:

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

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

Questo stamperà:

name of class
name of instance

Nota che la proprietà della classe è appena impostata nel corpo della classe, mentre la proprietà dell'istanza è impostata nel metodo __init__ .

Nel tuo caso, imposti Person.name sull'oggetto con il metodo personalizzato __eq__ che restituisce un lambda, qualcosa del genere:

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)

Stampa:

True
False

Questo sta certamente andando oltre il limite di essere "troppo intelligente", quindi sarei molto cauto nell'usarlo nel codice di produzione. Un lambda esplicito sarebbe probabilmente molto più chiaro per i futuri manutentori, anche se è un po 'più dettagliato.

La magia è nella proprietà Person.name, che risulta in un tipo che sovraccarica __eq__ (& amp; c) per restituire i non-bool. Le fonti di Storm sono online per consentirti di navigare (e imitare ATTENZIONE ;-) su http://bazaar.launchpad.net/~storm/storm/trunk/files/head%3A/storm/ - come vedrai, non diventano chiari su " ; magia nera " ;-)

A me non sembra un lambda di pitone. Non ho letto il codice per Storm ma Miles probabilmente ha ragione nel fatto che utilizza uno schema di valutazione pigro.

Per saperne di più sulle funzioni di Python Lambda leggi l'eccellente capitolo di Dive Into Python .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top