2009-05-04 7 views
5

Я прочитал учебник Штурмовой ОРМ по адресу https://storm.canonical.com/Tutorial, и я наткнулся на следующий фрагмент кода:какая функция python проиллюстрирована в этом коде?


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

Я не уверен, что второй аргумент найти метод будет оценен в True/False. Я думаю, это будет интерпретироваться как лямбда. Если это так, как я могу добиться такого же эффекта в своих функциях?

ответ

0

, так как я программист на Java ... Я предполагаю ... это перегрузка оператора? Person.name == оператор перегружен, что вместо того, чтобы сделать сравнение ... это производит SQL-запрос

мой 0,02 $

+0

Перегрузка Java и оператора ... не думайте, что это когда-либо произойдет. С другой стороны, может быть, вы правы. – Geo

+10

Нечетный .... Принимая ответ «угадывания», когда другой ответ основан на фактическом исходном коде в Storm. –

+0

извините, но моя догадка была «достаточно быстрой» :-) PS, вы правы, это очень странно! – dfa

1

Он не похож на питона лямбда мне. Я не читал код для Storm, но Майлз, вероятно, прав в том, что он использует ленивую схему оценки.

Чтобы узнать больше о функциях лямбда-функции python, прочитайте отлично chapter из Dive Into Python.

+0

Я всегда думал, что лямбда-функции должны быть префиксами по ключевому слову лямбда, так что это не может быть так, правильно? – Geo

22

Person.name имеет перегруженный метод __eq__, который возвращает не логическое значение, а объект, который хранит обе стороны выражения; этот объект может быть исследован методом find() для получения атрибута и значения, которые он будет использовать для фильтрации. Я бы описал это как тип ленивой модели оценки.

In Storm, он реализован с помощью Comparable object.

8

Магия в свойстве Person.name, что приводит к типу, который перегружает __eq__ (& c), чтобы вернуть non-bools. Источники шторма он-лайн для вас, чтобы просмотреть (и ОСТОРОЖНЫМ подражать ;-) в http://bazaar.launchpad.net/~storm/storm/trunk/files/head%3A/storm/ - как вы увидите, что они не идут свет на «черной магии» ;-)

9

Person.name является экземпляром некоторого типа с пользовательским методом __eq__. В то время как __eq__ обычно возвращает значение boolean (ish), оно может фактически вернуть все, что вы хотите, включая лямбда. См. Python special method names для получения дополнительных сведений об этом и связанных с ним методах.

Вероятно, наиболее запутанным/вводящие в заблуждение часть этого (особенно если вы привыкли к другим языкам OO, как Java) является то, что Person.name и person.name (где person является экземпляром Person) не должны иметь никакого отношения к друг друга. Например:

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__ метод, который возвращает лямбда, что-то вроде этого:

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 

Это, конечно, обойдя край «слишком умного», поэтому я бы очень осторожно относился к этому в производственном коде. Явная лямбда, вероятно, будет намного яснее будущим сопровождающим, даже если это немного более многословно.

+0

+1 за отличное объяснение «слишком умной» части! – lothar

Смежные вопросы