如何退出if子句

Rom*_*man 87 python control-flow

过早退出if条款有哪些方法?

有时我正在编写代码并希望breakif子句中放置一个语句,只记住那些只能用于循环.

让我们以下面的代码为例:

if some_condition:
   ...
   if condition_a:
       # do something
       # and then exit the outer if block
   ...
   if condition_b:
       # do something
       # and then exit the outer if block
   # more code here
Run Code Online (Sandbox Code Playgroud)

我可以想到一种方法:假设退出情况发生在嵌套的if语句中,将剩余的代码包装在一个大的else块中.例:

if some_condition:
   ...
   if condition_a:
       # do something
       # and then exit the outer if block
   else:
       ...
       if condition_b:
           # do something
           # and then exit the outer if block
       else:
           # more code here
Run Code Online (Sandbox Code Playgroud)

这样做的问题是更多的退出位置意味着更多的嵌套/缩进代码.

或者,我可以编写我的代码,使if条款尽可能小,不需要任何退出.

有没有人知道退出if条款的好/更好的方法?

如果有任何关联的else-if和else子句,我认为退出会跳过它们.

Dre*_*ann 86

(此方法适用于ifs,多个嵌套循环和其他您无法break轻松完成的构造.)

将代码包装在自己的函数中.而不是break,使用return.

例:

def some_function():
    if condition_a:
        # do something and return early
        ...
        return
    ...
    if condition_b:
        # do something else and return early
        ...
        return
    ...
    return

if outer_condition:
    ...
    some_function()
    ...
Run Code Online (Sandbox Code Playgroud)

  • 有一个古老的轶事:"丹尼斯·里奇鼓励模块化,通过告诉所有和各种各样的函数调用在C中真的非常便宜.每个人都开始编写小函数和模块化.多年后我们发现在PDP-11上函数调用仍然很昂贵和VAX代码经常花费50%的时间在CALLS指令上.Dennis曾向我们撒谎!但为时已晚;我们都被迷住了......" (12认同)
  • 我很高兴加入你的程序员技巧.根据我的经验,这种方法几乎每次你都试图使用向前移动的goto.(它既提示并解决了单个函数变得太大的情况) (4认同)
  • 这个引用来自"Unix编程的艺术"一书的第4章(在线http://www.faqs.org/docs/artu/).如果你以前没有,你真的应该阅读整个事情. (4认同)
  • 理想情况下,您可以实现这两者,但有时您必须交易良好的代码以获得良好的性能.这些时间很少见,特别是当您考虑使用Python时.换句话说:不要太担心函数调用开销. (2认同)

eph*_*ent 44

from goto import goto, label

if some_condition:
   ...
   if condition_a:
       # do something
       # and then exit the outer if block
       goto .end
   ...
   if condition_b:
       # do something
       # and then exit the outer if block
       goto .end
   # more code here

label .end

(请不要实际使用它.)

  • +1因为这很有趣.谷歌搜索向我透露,这是一个愚人节的笑话模块. (26认同)
  • 这让我想起了具有各种分支的汇编代码:) (3认同)
  • 我也联系了它.点击第一个`goto`. (2认同)
  • @ephemient:啊,没注意到链接.想象它是代码突出显示.但是现在我看了你的代码,我没有看到任何真正的突出显示... (2认同)
  • @ephemient只是出于好奇,为什么我们不应该使用这个? (2认同)

Tho*_*ing 21

while some_condition:
   ...
   if condition_a:
       # do something
       break
   ...
   if condition_b:
       # do something
       break
   # more code here
   break
Run Code Online (Sandbox Code Playgroud)

  • 请注意,您可以保留原始if并将整个事物包装在`while True:`中.请务必在最后输入一个"break"语句!对于具有do-while构造的语言,它更具有idomatic:`do {可以有条件地突破的代码} while(false);` (6认同)
  • 哦,嘿,我真的很喜欢这个主意.我认为这完全解决了我原来的愿望.但是,我有一种唠叨的感觉,这不是一个好的做法(因此,我将保留目前接受的答案,因为它促进了良好的编码风格). (3认同)

Mic*_*zyk 10

您可以使用例外模拟goto的功能:

try:
    # blah, blah ...
    # raise MyFunkyException as soon as you want out
except MyFunkyException:
    pass
Run Code Online (Sandbox Code Playgroud)

免责声明:我的意思是提醒您注意以这种方式做事的可能性,而在正常情况下我绝不认为这是合理的.正如我在关于这个问题的评论中提到的那样,构建代码以便首先避免拜占庭条件是可取的.:-)


gho*_*g74 5

可能是这个吗?

if some_condition and condition_a:
       # do something
elif some_condition and condition_b:
           # do something
           # and then exit the outer if block
elif some_condition and not condition_b:
           # more code here
else:
     #blah
if
Run Code Online (Sandbox Code Playgroud)


Enk*_*nki 5

一般来说,不要。如果您嵌套“如果”并打破它们,那么您就做错了。

但是,如果您必须:

if condition_a:
   def condition_a_fun():
       do_stuff()
       if we_wanna_escape:
           return
   condition_a_fun()
if condition_b:
   def condition_b_fun():
       do_more_stuff()
       if we_wanna_get_out_again:
           return
   condition_b_fun()
Run Code Online (Sandbox Code Playgroud)

请注意,这些函数不必在 if 语句中声明,它们可以提前声明;)这将是一个更好的选择,因为它将避免稍后需要重构丑陋的 if/then。


izz*_*kin 5

对于实际提出的要求,我的方法是将这些ifs放入一个单循环的循环中

while (True):
    if (some_condition):
        ...
        if (condition_a):
            # do something
            # and then exit the outer if block
            break
        ...
        if (condition_b):
            # do something
            # and then exit the outer if block
            break
        # more code here
    # make sure it is looped once
    break
Run Code Online (Sandbox Code Playgroud)

测试一下:

conditions = [True,False]
some_condition = True

for condition_a in conditions:
    for condition_b in conditions:
        print("\n")
        print("with condition_a", condition_a)
        print("with condition_b", condition_b)
        while (True):
            if (some_condition):
                print("checkpoint 1")
                if (condition_a):
                    # do something
                    # and then exit the outer if block
                    print("checkpoint 2")
                    break
                print ("checkpoint 3")
                if (condition_b):
                    # do something
                    # and then exit the outer if block
                    print("checkpoint 4")
                    break
                print ("checkpoint 5")
                # more code here
            # make sure it is looped once
            break
Run Code Online (Sandbox Code Playgroud)

  • 可能会考虑使用“for _ in range(1):”而不是“while True:”。(1) 更好地传达单次迭代循环的意图,并且 (2) 没有最后一个中断语句来退出循环(稍后可能会被意外删除) (3认同)
  • 老实说,这是最干净的解决方案。代码何时退出非常清楚 - 您不必担心函数内部的函数作用域,并且性能或逻辑债务为零。 (2认同)

Don*_*ong 5

还有另一种方法,它不依赖于定义函数(因为有时对于小代码片段来说可读性较差),不使用额外的外部 while 循环(这可能需要在注释中进行特别欣赏,以便第一眼就能理解) ,不使用 goto (...),最重要的是让你保持外部的缩进级别,这样你就不必开始嵌套东西。

if some_condition:
   ...
   if condition_a:
       # do something
       exit_if=True # and then exit the outer if block
if some condition and not exit_if: # if and only if exit_if wasn't set we want to execute the following code
   # keep doing something
   if condition_b:
       # do something
       exit_if=True # and then exit the outer if block
if some condition and not exit_if:
   # keep doing something
Run Code Online (Sandbox Code Playgroud)

是的,这还需要重新考虑可读性,但是,如果代码片段很小,则不需要跟踪任何永远不会重复的 while 循环,并且在了解中间 if 的用途后,它很容易阅读,全部都在一处且具有相同的缩进。

而且它应该非常有效。