这段代码中说明了什么python功能?

时间:2009-05-04 20:21:03

标签: python language-features

我在https://storm.canonical.com/Tutorial阅读了Storm ORM的教程,我偶然发现了以下代码:


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

我不确定 find 方法的第二个参数是否会被评估为True / False。我认为它将被解释为lambda。如果这是真的,我怎样才能在我的功能中达到同样的效果呢?

5 个答案:

答案 0 :(得分:22)

Person.name有一个重载的__eq__方法,它不返回布尔值,而是一个存储表达式两边的对象;可以通过find()方法检查该对象,以获取将用于过滤的属性和值。我会将此描述为一种懒惰的评估模式。

在Storm中,它是使用Comparable object实现的。

答案 1 :(得分:9)

Person.name是具有自定义__eq__方法的某种类型的实例。虽然__eq__通常返回一个布尔值(ish),但它实际上可以返回任何你想要的值,包括lambda。有关此方法和相关方法的更多信息,请参阅Python special method names

可能最令人困惑/误导的部分(特别是如果你已经习惯了其他OO语言,如Java)是Person.nameperson.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)

因为我是一名Java程序员......我猜... 它是运算符重载? Person.name ==是一个重载的运算符,而是进行比较...它产生一个SQL查询

我的0.02美元