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对象实现的.
Person.name是具有自定义__eq__方法的某种类型的实例.虽然__eq__通常返回一个布尔值(ish),但它实际上可以返回任何你想要的值,包括lambda.有关此方法和相关方法的更多信息,请参阅Python特殊方法名称
可能是这个中最令人困惑/误导的部分(特别是如果你已经习惯了像Java这样的其他OO语言)就是那个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
Run Code Online (Sandbox Code Playgroud)
这将打印:
Run Code Online (Sandbox Code Playgroud)name of class name of instance
请注意,类属性只是在类体中设置,而实例属性是在__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可能会更加清晰,即使它有点冗长.
神奇的是在Person.name属性中,这会导致一个类型重载__eq__(&c)以返回非bool.Storm的消息来源在线供你浏览(并且可以模仿;-)来http://bazaar.launchpad.net/~storm/storm/trunk/files/head%3A/storm/ - 你会看到,他们不要轻视"黑魔法";-)
因为我是一名 Java 程序员...我猜...这是运算符重载?Person.name == 是一个重载的运算符,它会进行比较...它会生成一个 SQL 查询
我的 0.02$