【问题标题】:How does Python determine operand precedence for ==?Python 如何确定 == 的操作数优先级?
【发布时间】:2020-06-09 20:49:48
【问题描述】:

lists 与== 运算符进行比较会返回bool

>>> [0,0,0] == [0,1,0]
False

numpy 数组与== 运算符进行比较会返回另一个由元素比较产生的数组。

>>> np.array([0,0,0]) == np.array([0,1,0])
array([ True, False,  True])

如果我混合操作数类型,numpy 方法总是优先。

>>> np.array([0,0,0]) == [0,1,0]
array([ True, False,  True])
>>> [0,0,0] == np.array([0,1,0])
array([ True, False,  True])

Python 如何确定哪个操作数优先?我的问题与Python 的机制有关,而不是numpylist

【问题讨论】:

  • 如果 == 是一个 numpy 操作,它将有效地获取 RHS 并在其周围抛出一个 np.asarray() 以将其强制为一个 numpy 数组。这称为运算符优先级。
  • == 成为numpy 操作意味着什么?这是否意味着array 在 LHS 上?如果是这样,您的回答是有道理的,但如果 array 在 RHS 上,它如何解决?
  • list.__eq__np.ndarray.__eq__
  • 是的,但是== 怎么知道是使用 list.__eq__ 还是 np.ndarray.__eq__?它是根据 LHS 操作数还是其他一些标准来确定这一点?
  • 这不是运算符优先级的问题,只有一个运算符。基本上,一个定义良好的比较运算符钩子,比如__eq__,如果它不知道如何处理其他类型,它将返回NotImplemented,然后比较推迟到该类型__eq__ 在@987654321 中阅读有关它的信息@

标签: python numpy operator-overloading equals


【解决方案1】:

富比较运算符总是先询问左操作数(除非右操作数是左类型的子类的实例;这里不是这种情况)。如果检查的第一个操作数返回 NotImplemented(与 numpy 数组比较时,list 总是会这样做,因为它不可能知道它们被嵌入到核心解释器中),那么要求第二个操作数执行反射比较(__eq__ 不会改变)。

由于numpylist 的知识烘焙到其__eq__ 中,而list 没有烘焙numpy 数组的知识,numpy 要么先行,要么立即使用自己的逻辑(当它左操作数)或list先行(当它是左操作数时),通过返回NotImplemented放弃,然后numpy__eq__进行最后的调用。

left == right 调用的粗略内部结构(省略子类特殊情况):

attempt = type(left).__eq__(left, right)
if attempt is NotImplemented:
   attempt = type(right).__eq__(right, left)
   if attempt is NotImplemented:
       attempt = False  # Specific to __eq__, if both can't compare, returns False
return attempt

详情请从the NotImplemented docs开始,沿着黄砖路走(阅读:链接)。

【讨论】:

    【解决方案2】:

    在 Python 中,左操作数总是在右操作数之前计算。这也适用于函数参数。

    在评估涉及andor 运算符的表达式时,Python 使用短路。使用这些运算符时,Python 不会计算第二个操作数,除非需要解析结果。这使得if (s != None)(len(s) < 10): ... 等语句能够可靠地工作。

    year % 4 == 0 and year % 100 != 0 or year % 400 == 0

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-13
      • 1970-01-01
      • 2012-09-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多