Python调试模式下的`pass`有什么作用

时间:2019-11-17 22:36:59

标签: python

我只是偶然发现了这种现象。

mylist = [('1',), ('2',), ('3',), ('4',)]
for l in mylist:
    print(l)
    pass    # first pass
pass        # second pass
print("end")

如果我将红色停止点设置在第一个pass并进行调试,程序将在此处停止,输出为:

('1',)

但是,如果我将红色停止点设置在第二个pass并进行调试,则输出将在最后一行包含end。似乎pass避免在这一点上停止,只是让程序进一步运行。

我认为pass应该没有真正的意义,但似乎没有意义。那么如何理解pass

谢谢大家

3 个答案:

答案 0 :(得分:2)

pass只是语法分析器,语法分析器知道语句有意留空。它不会生成操作码,因此,调试器在被击中时无法暂停。相反,当执行下一条指令时,您会看到它停止。

您可以通过打印由空函数生成的操作码来查看此信息:

>>> def test():
...   pass
...
>>> import dis
>>> dis.dis(test)
  2           0 LOAD_CONST               0 (None)
              3 RETURN_VALUE

答案 1 :(得分:2)

"<< *polynode->Childs[i]"不执行任何操作。它编译为没有字节码。但是,跳回到循环开头的字节码与循环中最后一条语句的行相关联,并且pass计数。如果在Python 3.7.3上进行反编译,则如下所示:

pass

输出:

import dis
dis.dis(r'''mylist = [('1',), ('2',), ('3',), ('4',)]
for l in mylist:
    print(l)
    pass    # first pass
pass        # second pass
print("end")''')

1 0 LOAD_CONST 0 (('1',)) 2 LOAD_CONST 1 (('2',)) 4 LOAD_CONST 2 (('3',)) 6 LOAD_CONST 3 (('4',)) 8 BUILD_LIST 4 10 STORE_NAME 0 (mylist) 2 12 SETUP_LOOP 20 (to 34) 14 LOAD_NAME 0 (mylist) 16 GET_ITER >> 18 FOR_ITER 12 (to 32) 20 STORE_NAME 1 (l) 3 22 LOAD_NAME 2 (print) 24 LOAD_NAME 1 (l) 26 CALL_FUNCTION 1 28 POP_TOP 4 30 JUMP_ABSOLUTE 18 >> 32 POP_BLOCK 6 >> 34 LOAD_NAME 2 (print) 36 LOAD_CONST 4 ('end') 38 CALL_FUNCTION 1 40 POP_TOP 42 LOAD_CONST 5 (None) 44 RETURN_VALUE JUMP_ABSOLUTE与第4行(第一个POP_BLOCK)相关联。

在第一个pass上设置断点时,Python在pass之前中断。当您在第二个JUMP_ABSOLUTE上设置断点时,第5行没有任何字节码与之关联,因此Python在第6行中断了,而第6行确实具有字节码。

答案 2 :(得分:0)

pass只是一个空运算符,如果您想退出for循环,则需要使用break。在第二遍看到mylist输出结束的原因是,第一遍只是继续for循环。