if语句中continue上的断点未命中

2024-10-03 11:18:06 发布

您现在位置:Python中文网/ 问答频道 /正文

在下面的代码中,ab都是生成器函数的输出,可以计算为None或具有值

def testBehaviour(self):
  a = None
  b = 5

  while True:
    if not a or not b:
      continue
    print('blaat')

如果我将断点(使用VisualStudio代码)放在带有continue语句的行上,以及带有print语句的行上,则两者都不会命中。不会调用print语句,循环会像预期的那样无限期地运行,但我希望会命中断点

如果我将代码更改为以下之一:

def testBehaviour(self):
  a = None
  b = 5

  while True:
    if not a:
      continue
    print('blaat')

或:

def testBehaviour(self):
  a = None
  b = 5

  while True:
    if not a or not b:
      c = 'dummy'
      continue
    print('blaat')

再次在带有continueprint语句的行上放置断点,断点被命中

谁能告诉我为什么断点没有命中?这似乎不仅仅发生在VisualStudio代码中,因为我们的代码覆盖率工具还声明没有调用continue语句

这是在Windows7上的Python2.7上,32位


Tags: 代码selfnonetrueifdefnot语句
1条回答
网友
1楼 · 发布于 2024-10-03 11:18:06

操作码中有一个优化,编译器识别if expr: continue

当使用if not a or not b:

 11          12 SETUP_LOOP              35 (to 50)
        >>   15 LOAD_GLOBAL              1 (True)
             18 POP_JUMP_IF_FALSE       49

 12          21 LOAD_FAST                1 (a)
             24 UNARY_NOT
             25 POP_JUMP_IF_TRUE        15
             28 LOAD_FAST                2 (b)
             31 UNARY_NOT
             32 POP_JUMP_IF_FALSE       41

 13          35 JUMP_ABSOLUTE           15
             38 JUMP_FORWARD             0 (to 41)

 14     >>   41 LOAD_CONST               2 ('blaat')
             44 PRINT_ITEM
             45 PRINT_NEWLINE
             46 JUMP_ABSOLUTE           15
        >>   49 POP_BLOCK
        >>   50 LOAD_CONST               0 (None)
             53 RETURN_VALUE

如果not a为true,则行25 POP_JUMP_IF_TRUE 15跳回while循环的开始(行15)。它永远不会到达continue语句的行35 JUMP_ABSOLUTE 15

如果您切换ab的值,这个测试用例可以工作

如果将测试表达式重写为if not ( a and b ):,则会得到以下操作码

 11          12 SETUP_LOOP              33 (to 48)
        >>   15 LOAD_GLOBAL              1 (True)
             18 POP_JUMP_IF_FALSE       47

 12          21 LOAD_FAST                1 (a)
             24 JUMP_IF_FALSE_OR_POP    30
             27 LOAD_FAST                2 (b)
        >>   30 POP_JUMP_IF_TRUE        39

 13          33 JUMP_ABSOLUTE           15
             36 JUMP_FORWARD             0 (to 39)

 14     >>   39 LOAD_CONST               2 ('blaat')
             42 PRINT_ITEM
             43 PRINT_NEWLINE
             44 JUMP_ABSOLUTE           15
        >>   47 POP_BLOCK
        >>   48 LOAD_CONST               0 (None)
             51 RETURN_VALUE

这总是有效的,而且速度更快。not操作被优化到跳转测试语句中

相关问题 更多 >