我在https://storm.canonical.com/Tutorial阅读了Storm ORM的教程,我偶然发现了以下代码:
store.find(Person, Person.name == u"Mary Margaret").set(name=u"Mary Maggie")
我不确定 find 方法的第二个参数是否会被评估为True / False。我认为它将被解释为lambda。如果这是真的,我怎样才能在我的功能中达到同样的效果呢?
答案 0 :(得分:22)
Person.name
有一个重载的__eq__
方法,它不返回布尔值,而是一个存储表达式两边的对象;可以通过find()
方法检查该对象,以获取将用于过滤的属性和值。我会将此描述为一种懒惰的评估模式。
在Storm中,它是使用Comparable
object实现的。
答案 1 :(得分:9)
Person.name
是具有自定义__eq__
方法的某种类型的实例。虽然__eq__
通常返回一个布尔值(ish),但它实际上可以返回任何你想要的值,包括lambda。有关此方法和相关方法的更多信息,请参阅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
请注意,class属性只是在类体中设置,而实例属性是在__init__
方法中设置的。
在您的情况下,您使用返回lambda的自定义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
这肯定是在“太聪明”的边缘,所以我在生产代码中使用它会非常谨慎。对于未来的维护者来说,明确的lambda可能会更加清晰,即使它有点冗长。
答案 2 :(得分:8)
魔术在Person.name属性中,这导致一个类型重载__eq__
(& c)以返回非bool。 Storm的消息来源在线供您浏览(并且在http://bazaar.launchpad.net/~storm/storm/trunk/files/head%3A/storm/时可以模仿;-) - 正如您所看到的,他们不会对“黑魔法”有所了解; - )
答案 3 :(得分:1)
对我来说它看起来不像是一个蟒蛇lambda。我没有阅读Storm的代码,但Miles可能是正确的,因为它使用了懒惰的评估模式。
要了解有关python lambda函数的更多信息,请阅读chapter的优秀Dive Into Python。
答案 4 :(得分:0)
我的0.02美元