“in"的结合性在 Python 中? [英] Associativity of "in" in Python?

查看:29
本文介绍了“in"的结合性在 Python 中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作一个 Python 解析器,这真的让我很困惑:

<预><代码>>>>1 in [] in 'a'错误的>>>(1 in []) in 'a'类型错误:'in '需要字符串作为左操作数,而不是 bool>>>1 in ([] in 'a')类型错误:'in '需要字符串作为左操作数,而不是列表

in 在 Python 中究竟是如何工作的,关于结合性等?

为什么没有两个表达式的行为方式相同?

解决方案

1 in [] in 'a' 被计算为 (1 in []) and ([] in 'a')

由于第一个条件([] 中的1)是False,所以整个条件被评估为False([] in 'a') 从来没有被实际计算过,所以不会产生错误.

我们可以看到 Python 如何使用 dis 模块:

<预><代码>>>>从 dis 导入 dis>>>dis(1 in [] in 'a'")1 0 LOAD_CONST 0 (1)2 BUILD_LIST 04 DUP_TOP6 ROT_THREE8 CONTAINS_OP 0 # `in` 是包含操作符10 JUMP_IF_FALSE_OR_POP 18 # 如果第一个跳到 18# 比较是假的12 LOAD_CONST 1 ('a') # 12-16 永远不会被执行14 CONTAINS_OP 0 # 所以这里没有错误 (14)16 RETURN_VALUE>>18 ROT_TWO20 POP_TOP22 RETURN_VALUE>>>dis("(1 in []) in 'a'")1 0 LOAD_CONST 0 (1)2 LOAD_CONST 1 (())4 CONTAINS_OP 0 # 在 [] 中执行 16 LOAD_CONST 2 ('a') # 现在加载 'a'8 CONTAINS_OP 0 # 检查 (1 in []) 的结果是否在 'a'# 抛出错误,因为('a' 中为 False)# 是一个类型错误10 RETURN_VALUE>>>dis("1 in ([] in 'a')")1 0 LOAD_CONST 0 (1)2 BUILD_LIST 04 LOAD_CONST 1 ('a')6 CONTAINS_OP 0 # perform ([] in 'a'), 即# 不正确,所以它抛出一个类型错误8 CONTAINS_OP 0 # 如果没有错误,那么这将# 检查 1 是否在 ([] in 'a') 的结果中10 RETURN_VALUE


  1. 除了 [] 只计算一次.这在本例中无关紧要,但如果您(例如)将 [] 替换为返回列表的函数,则该函数只会被调用一次(最多).文档 也解释了这一点.

I'm making a Python parser, and this is really confusing me:

>>> 1 in [] in 'a'
False

>>> (1 in []) in 'a'
TypeError: 'in <string>' requires string as left operand, not bool

>>> 1 in ([] in 'a')
TypeError: 'in <string>' requires string as left operand, not list

How exactly does in work in Python, with regards to associativity, etc.?

Why do no two of these expressions behave the same way?

解决方案

1 in [] in 'a' is evaluated as (1 in []) and ([] in 'a')

Since the first condition (1 in []) is False, the whole condition is evaluated as False; ([] in 'a') is never actually evaluated, so no error is raised.

We can see how Python executes each statement using the dis module:

>>> from dis import dis
>>> dis("1 in [] in 'a'")
  1           0 LOAD_CONST               0 (1)
              2 BUILD_LIST               0
              4 DUP_TOP
              6 ROT_THREE
              8 CONTAINS_OP              0        # `in` is the contains operator
             10 JUMP_IF_FALSE_OR_POP    18        # skip to 18 if the first 
                                                  # comparison is false
             12 LOAD_CONST               1 ('a')  # 12-16 are never executed
             14 CONTAINS_OP              0        # so no error here (14)
             16 RETURN_VALUE
        >>   18 ROT_TWO
             20 POP_TOP
             22 RETURN_VALUE
>>> dis("(1 in []) in 'a'")
  1           0 LOAD_CONST               0 (1)
              2 LOAD_CONST               1 (())
              4 CONTAINS_OP              0        # perform 1 in []
              6 LOAD_CONST               2 ('a')  # now load 'a'
              8 CONTAINS_OP              0        # check if result of (1 in []) is in 'a'
                                                  # throws Error because (False in 'a')
                                                  # is a TypeError
             10 RETURN_VALUE
>>> dis("1 in ([] in 'a')")
  1           0 LOAD_CONST               0 (1)
              2 BUILD_LIST               0
              4 LOAD_CONST               1 ('a')
              6 CONTAINS_OP              0        # perform ([] in 'a'), which is 
                                                  # incorrect, so it throws a TypeError
              8 CONTAINS_OP              0        # if no Error then this would 
                                                  # check if 1 is in the result of ([] in 'a')
             10 RETURN_VALUE


  1. Except that [] is only evaluated once. This doesn't matter in this example but if you (for example) replaced [] with a function that returned a list, that function would only be called once (at most). The documentation explains also this.

这篇关于“in"的结合性在 Python 中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆