我最近有机会看看web2py框架,虽然我之前有过使用Django的经验,但对于普通的Python来说更是如此,我无法理解web2py使用的Query系统。
让我们从web2py book
中取这个例子db = DAL('sqlite://storage.db')
myquery = (db.mytable.myfield > 'A')
myset = db(myquery)
rows = myset.select()
for row in rows:
print row.myfield
In a SO comment web2py作者说(db.mytable.myfield > 'A')
没有直接评估为True / False,而是在选择时对每一行进行实际评估。我理解这是允许这些表达式用作查询对象甚至可以组合的原因。
我试图在网上找到答案,但不能,所以这是我的问题:这些查询表达式如何不立即评估为True / False?为什么myquery的值不是,比如说,True?我可能缺少哪些Python功能可以实现这个功能?
答案 0 :(得分:7)
其他答案都有,但只是为了提供更多的web2py特定细节:
db.mytable.myfield > 'A'
db.mytable.myfield
是web2py DAL Field
类的一个实例,它继承自DAL Expression
类。 Expression
类本身会重载许多Python运算符,例如==
,<
,>
等。这些重载运算符应用于Expression
时(因此Field
)对象返回DAL Query
类的实例,而不是标准的Python布尔对象。以下是>
(__gt__
)运算符的source code。
有关Python中运算符重载的更多信息,请参阅here。
答案 1 :(得分:2)
任何运算符都基于special methods的评估应用于自定义(非内置)对象。它被广泛称为operator overloading。 所以基本上字段类定义看起来很相似:
class DBField(...):
#...
def __gt__(self,value):
#building query object, based on value
return query
答案 2 :(得分:2)
db.mytable.myfield是一个gluon.sql.SQLField,它覆盖了__gt__
方法,因此表达式使用&gt;运算符在计算时产生gluon.sql.SQLQuery(参见http://www.web2py.com/examples/static/epydoc/web2py.gluon.dal.Expression-class.html)。