Tutorial :what python feature is illustrated in this code?



Question:

I read Storm ORM's tutorial at https://storm.canonical.com/Tutorial, and I stumbled upon the following piece of code :

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

I'm not sure that the second argument of the find method will be evaluated to True/False. I think it will be interpreted as a lambda. If that is true, how can I achieve the same effect in my functions ?


Solution:1

since I'm a Java programmer... I'm guessing... it is operator overloading? Person.name == is an operator overloaded that instead do comparison... it produces a SQL query

my 0.02$


Solution:2

Person.name has a overloaded __eq__ method that returns not a boolean value but an object that stores both sides of the expression; that object can be examined by the find() method to obtain the attribute and value that it will use for filtering. I would describe this as a type of lazy evaluation pattern.

In Storm, it is implemented with the Comparable object.


Solution:3

Person.name is an instance of some type with a custom __eq__ method. While __eq__ normally returns a boolean(ish) value, it can actually return whatever you want, including a lambda. See Python special method names for more on this and related methods.

Probably the most confusing/misleading part of this (especially if you're used to other OO languages like Java) is that Person.name and person.name (where person is an instance of Person) don't have to have any relationship to each other. For example:

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

This will print:

name of class  name of instance  

Note that the class property is just set in the class body, while the instance property is set in the __init__ method.

In your case, you'd set Person.name to the object with the custom __eq__ method that returns a lambda, something like this:

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)  

This prints:

True  False  

This is certainly skirting the edge of being "too clever", so I'd be very cautious about using this in production code. An explicit lambda would probably be a lot clearer to future maintainers, even if it is a bit more verbose.


Solution:4

The magic is in the Person.name property, which results in a type that overloads __eq__ (&c) to return non-bools. Storm's sources are online for you to browse (and CAUTIOUSLY imitate;-) at http://bazaar.launchpad.net/~storm/storm/trunk/files/head%3A/storm/ -- as you'll see, they don't go light on the "black magic";-)


Solution:5

It does not look like a python lambda to me. I did not read the code for Storm but Miles is probably right in that it uses a lazy evaluation schema.

To learn more about python lambda functions read the excellent chapter of Dive Into Python.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »