130

存在哪些过早退出if子句的方法?

有时我在编写代码并想在子句中放置一条break语句if,只是要记住那些只能用于循环。

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

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

我可以想到一种方法来做到这一点:假设退出情况发生在嵌套的 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

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

或者,我可以编写代码以使if子句尽可能小,并且不需要任何退出。

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

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

4

13 回答 13

128

(此方法适用于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()
    ...
于 2010-01-15T05:24:07.360 回答
73
转到导入转到,标签

如果某些条件:
   ...
   如果条件_a:
       # 做一点事
       # 然后退出外部 if 块
       转到.end
   ...
   如果条件_b:
       # 做一点事
       # 然后退出外部 if 块
       转到.end
   # 更多代码在这里

标签 .end

(请不要实际使用它。)

于 2010-01-15T05:29:47.377 回答
31
while some_condition:
   ...
   if condition_a:
       # do something
       break
   ...
   if condition_b:
       # do something
       break
   # more code here
   break
于 2010-01-19T02:05:03.893 回答
12

您可以模拟 goto 的功能,但有以下例外:

try:
    # blah, blah ...
    # raise MyFunkyException as soon as you want out
except MyFunkyException:
    pass

免责声明:我只是想让您注意以这种方式做事的可能性,而在正常情况下我绝不认可它是合理的。正如我在对该问题的评论中提到的那样,到目前为止,首先避免拜占庭条件的结构化代码是可取的。:-)

于 2010-01-15T05:35:05.340 回答
9

可能是这个?

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
于 2010-01-15T05:28:19.403 回答
7

对于实际询问的内容,我的方法是将这些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

测试它:

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
于 2015-09-08T08:10:49.573 回答
4

Generally speaking, don't. If you are nesting "ifs" and breaking from them, you are doing it wrong.

However, if you must:

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()

Note, the functions don't HAVE to be declared in the if statement, they can be declared in advance ;) This would be a better choice, since it will avoid needing to refactor out an ugly if/then later on.

于 2010-01-15T06:55:35.393 回答
4

还有另一种方法不依赖于定义函数(因为有时对于小代码片段来说可读性较差),不使用额外的外部 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

是的,这还需要再次查看可读性,但是,如果代码片段很小,则不需要跟踪任何不会重复的 while 循环,并且在了解中间 if 的用途之后,它很容易阅读,全部在一个地方和相同的缩进。

它应该非常有效。

于 2018-11-07T08:24:13.473 回答
1

实际上,您所描述的是 goto 语句,这些语句通常被大量平移。你的第二个例子更容易理解。

但是,更清洁的仍然是:

if some_condition:
   ...
   if condition_a:
       your_function1()
   else:
       your_function2()

...

def your_function2():
   if condition_b:
       # do something
       # and then exit the outer if block
   else:
       # more code here
于 2010-01-15T05:29:21.107 回答
0

所以在这里我明白你正试图打破外部if 代码块

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

解决这个问题的一种方法是,您可以在外部 if 块中测试错误条件,然后隐式退出代码块,然后使用 else 块嵌套其他 if 来做某事

if test_for_false:
    # Exit the code(which is the outer if code)

else:
    if condition_a:
        # Do something

    if condition_b:
        # Do something
于 2018-05-31T12:23:44.713 回答
0

这是处理此问题的另一种方法。它使用单个项目 for 循环,使您能够只使用 continue。它可以防止不必要地无缘无故地拥有额外的功能。并且另外消除了潜在的无限while循环。

if something:
    for _ in [0]:
        # Get x
        if not x:
            continue

        # Get y
        if not y:
            continue

        # Get z
        if not z:
            continue

        # Stuff that depends on x, y, and z
于 2020-04-15T18:18:18.237 回答
0

唯一可以在没有其他方法的情况下应用它的是elif以下示例

a = ['yearly', 'monthly', 'quartly', 'semiannual', 'monthly', 'quartly', 'semiannual', 'yearly']
# start the condition
if 'monthly' in b: 
    print('monthly') 
elif 'quartly' in b: 
    print('quartly') 
elif 'semiannual' in b: 
    print('semiannual') 
elif 'yearly' in b: 
    print('yearly') 
else: 
    print('final') 
于 2020-07-28T19:31:09.833 回答
-2

在 if 条件中使用return会将您从函数中返回,以便您可以使用 return 来打破 if 条件。

于 2018-10-18T10:13:24.323 回答