Как выйти из условия if - PullRequest
       35

Как выйти из условия if

76 голосов
/ 15 января 2010

Какие существуют методы для преждевременного выхода из условия 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, я полагаю, что выход из них пропустит их.

Ответы [ 11 ]

80 голосов
/ 15 января 2010

(Этот метод работает для if s, нескольких вложенных циклов и других конструкций, которые вы не можете 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()
    ...
42 голосов
/ 15 января 2010
from <a href="http://entrian.com/goto/" rel="noreferrer">goto</a> 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

(на самом деле не используйте это, пожалуйста.)

18 голосов
/ 19 января 2010
while some_condition:
   ...
   if condition_a:
       # do something
       break
   ...
   if condition_b:
       # do something
       break
   # more code here
   break
9 голосов
/ 15 января 2010

Вы можете эмулировать функциональность goto с исключениями:

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

Отказ от ответственности: я только хочу представить вашему вниманию возможность делать вещи таким образом, хотя я никоим образом не одобряю это как разумное в нормальных обстоятельствах. Как я уже упоминал в комментарии к этому вопросу, структурирование кода таким образом, чтобы избежать византийских условий, в первую очередь, предпочтительнее. : -)

5 голосов
/ 15 января 2010

это может быть?

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
4 голосов
/ 15 января 2010

Вообще говоря, нет. Если вы вкладываете «если» и отказываетесь от них, вы делаете это неправильно.

Однако, если вам необходимо:

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

Обратите внимание, что функции НЕ ДОЛЖНЫ быть объявлены в операторе if, они могут быть объявлены заранее;) Это был бы лучший выбор, так как это позволит избежать необходимости рефакторинга уродливого if / then позже.

3 голосов
/ 08 сентября 2015

Для того, что на самом деле было задано, мой подход состоит в том, чтобы поместить эти if в один петля

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
1 голос
/ 07 ноября 2018

Есть еще один способ, который не основан на определении функций (потому что иногда он менее читабелен для небольших фрагментов кода), не использует дополнительный внешний цикл 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, это легко читается. , все в одном месте и с одинаковыми отступами.

И это должно быть довольно эффективно.

1 голос
/ 15 января 2010

По сути, вы описываете операторы 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
0 голосов
/ 18 октября 2018

используйте return в условии if, которое возвращает вас из функции, так что вы можете использовать return, чтобы нарушить условие if.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...