为啥这个python表达式参数在调用时没有展开?

Posted

技术标签:

【中文标题】为啥这个python表达式参数在调用时没有展开?【英文标题】:Why is this python expression parameter is not expanded at call time?为什么这个python表达式参数在调用时没有展开? 【发布时间】:2018-04-22 13:33:37 【问题描述】:

在 google appengine NDB there are queries 中像这样:

query = Account.query(Account.userid >= 40)

为什么Account.userid >= 40 表达式在作为参数传递之前没有在调用时扩展为真或假?过滤器表达式是如何传递给查询的?是通过运算符重载完成的吗?

【问题讨论】:

可能是因为 LH 操作数是一个适当定义魔术方法的对象。 是的,这就是我所说的运算符重载的意思。看起来很漂亮,但也令人困惑。 我不认为这是一个骗局,值得更详细地回答。如果您有类似if Account.userid >= 40: 的构造,则不等式解析为 True,但如果它是在查询的上下文中,则会发生某种神奇的事情。 【参考方案1】:

Ignacio 是正确的,NDB 代码在其Property class 上定义自定义魔术方法以进行比较检查。这些函数(__eq____ne____lt__ 等)都在后台调用 this custom _comparison function。

def _comparison(self, op, value):
    """Internal helper for comparison operators.
    Args:
      op: The operator ('=', '<' etc.).
    Returns:
      A FilterNode instance representing the requested comparison.
    """
    # NOTE: This is also used by query.gql().
    if not self._indexed:
      raise datastore_errors.BadFilterError(
          'Cannot query for unindexed property %s' % self._name)
    from .query import FilterNode  # Import late to avoid circular imports.
    if value is not None:
      value = self._do_validate(value)
      value = self._call_to_base_type(value)
      value = self._datastore_type(value)
    return FilterNode(self._name, op, value)

如您所见,代码不返回布尔结果,而是返回FilterNode 的实例,该实例本身的计算结果为适合比较的真/假值。

为什么Account.userid &gt;= 40 表达式在作为参数传递之前没有在调用时扩展为真或假?

从技术上讲,它在调用 query() 函数之前得到扩展/评估,它只是没有评估为布尔值。

【讨论】:

以上是关于为啥这个python表达式参数在调用时没有展开?的主要内容,如果未能解决你的问题,请参考以下文章

有没有一种更 Pythonic 的方式来在函数的参数上展开列表?

makefile之call函数

为啥直接调用 Python 脚本时 argparse 无法识别参数?

为啥我收到错误:致命错误:在展开可选值时意外发现 nil?

power query展开表时动态获取要展开的列

为啥这个正则表达式调用 substcont 次数过多?