Question

J'ai lu le didacticiel de Storm ORM à l'adresse https://storm.canonical.com/Tutorial , et Je suis tombé sur le code suivant:


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

Je ne suis pas sûr que le deuxième argument de la méthode find soit évalué à True / False. Je pense que cela sera interprété comme un lambda. Si cela est vrai, comment puis-je obtenir le même effet dans mes fonctions?

Était-ce utile?

La solution

depuis que je suis un programmeur Java ... je devine ... c'est la surcharge de l'opérateur? Person.name == est un opérateur surchargé qui effectue une comparaison ... il génère une requête SQL

mon 0.02 $

Autres conseils

Person.name contient une méthode __ eq __ surchargée qui ne renvoie pas une valeur booléenne mais un objet stockant les deux côtés de l'expression; Cet objet peut être examiné par la méthode find () pour obtenir l'attribut et la valeur qu'il utilisera pour le filtrage. Je décrirais cela comme un type de modèle d'évaluation paresseux.

Dans Storm, il est implémenté avec le Objet comparable .

Person.name est une instance d'un type donné avec une méthode personnalisée __ eq __ . Alors que __ eq __ renvoie normalement une valeur booléenne (ish), il peut en réalité renvoyer ce que vous voulez, y compris un lambda. Consultez les noms de méthodes spéciales Python pour plus d'informations sur cela et sur les méthodes associées. .

La partie la plus déroutante / trompeuse de ce problème (surtout si vous êtes habitué à d'autres langages OO tels que Java) est que Person.name et person.name ( où personne est une instance de Personne ) ne doit avoir aucune relation les uns avec les autres. Par exemple:

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

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

Ceci imprimera:

name of class
name of instance

Notez que la propriété de classe est simplement définie dans le corps de la classe, tandis que la propriété d'instance est définie dans la méthode __ init __ .

Dans votre cas, vous auriez défini Person.name sur l'objet avec la méthode personnalisée __ eq __ qui renvoie un lambda, à peu près comme ceci:

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)

Ceci imprime:

True
False

Ceci est certainement à l’écart de "trop ??intelligent", je serais donc très prudent de l’utiliser dans le code de production. Un lambda explicite serait probablement beaucoup plus clair pour les futurs responsables, même s’il est un peu plus détaillé.

La magie se trouve dans la propriété Person.name, ce qui entraîne un type qui surcharge __ eq __ (& amp) pour renvoyer des non-bools. Les sources de Storm sont en ligne pour que vous puissiez les parcourir (et les imiter prudemment ;-) à http://bazaar.launchpad.net/~storm/storm/trunk/files/head%3A/storm/ - comme vous le verrez, ils ne vont pas à la légère ; magie noire " ;; -)

Pour moi, ça ne ressemble pas à un python lambda. Je n'ai pas lu le code de Storm, mais Miles a probablement raison en ce sens qu'il utilise un schéma d'évaluation paresseux.

Pour en savoir plus sur les fonctions lambda de python, consultez l'excellent chapitre de Plongez au coeur de Python .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top