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

Geo*_*Geo 5 python language-features

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


store.find(Person, Person.name == u"Mary Margaret").set(name=u"Mary Maggie")
Run Code Online (Sandbox Code Playgroud)

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

Mil*_*les 22

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

在Storm中,它是用Comparable对象实现的.


Lau*_*ves 9

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

可能是这个中最令人困惑/误导的部分(特别是如果你已经习惯了像Java这样的其他OO语言)就是那个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
Run Code Online (Sandbox Code Playgroud)

这将打印:

name of class
name of instance
Run Code Online (Sandbox Code Playgroud)

请注意,类属性只是在类体中设置,而实例属性是在__init__方法中设置的.

在您的情况下,您将Person.name使用__eq__返回lambda 的自定义方法设置对象,如下所示:

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)
Run Code Online (Sandbox Code Playgroud)

这打印:

True
False
Run Code Online (Sandbox Code Playgroud)

这肯定是在"太聪明"的边缘,所以我在生产代码中使用它会非常谨慎.对于未来的维护者来说,明确的lambda可能会更加清晰,即使它有点冗长.


Ale*_*lli 8

神奇的是在Person.name属性中,这会导致一个类型重载__eq__(&c)以返回非bool.Storm的消息来源在线供你浏览(并且可以模仿;-)来http://bazaar.launchpad.net/~storm/storm/trunk/files/head%3A/storm/ - 你会看到,他们不要轻视"黑魔法";-)


dfa*_*dfa 0

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

我的 0.02$

  • 奇怪......当另一个答案基于 Storm 中的实际源代码时接受“猜测”答案。 (10认同)