8

在 C 语言中,有一个巧妙的技巧可以让您通过以下方式避免金字塔式代码:

if (check1())
  if (check2())
    if (check3())
      do_something();

进入:

do {
  if (!check1())
    break;

  if (!check2())
    break;

  if (!check3())
    break;

  do_something();
} while (0);

我在没有 do-while 构造的 Python 中做到这一点的最干净的方法是什么?

注意:我不一定要求一种在 Python 中实现 do-while 循环的方法,而是一种避免上述金字塔式代码的技术。

更新:似乎有些混乱。我使用循环的唯一原因是能够在主体中的任何点突破,这应该只执行一次。

基本上我在 Python 中所做的是:

while True:
    if not check1():
        break

    if not check2():
        break

    if not check3():
        break

    do_domething()
    break

我只是想知道是否有更清洁的方法。

4

8 回答 8

7

Pythonic 的写法是

if check1() and check2() and check3():
    do_something()

在 Python 中,我们强调代码的清晰和简单,而不是使用聪明的编程技巧。


[编辑] 如果您需要“创建一个变量并在第一次检查中使用它”,那么您将使用金字塔样式:

if check1():
    #variables and stuff here
    if check2():
        #variables and stuff here
        if check3():
            doSomething()

或者,正如@Blender 建议的那样,将其重构为一个单独的方法。这些都是比使用不打算循环的循环更简单、更清晰的方式来传达您的意图。

于 2013-07-19T18:31:08.263 回答
5

反转你的条件并尽早爆发。如果你的代码结构很好,你首先就不必担心if楼梯:

def do_bigger_something():
    if not check1():
        return

    if not check2():
        return

    if not check3():
        return

    do_something()

很有可能,如果您的代码的一部分进行了很多这些检查,那么无论如何它都应该变成一个函数。

于 2013-07-19T18:27:35.047 回答
2
if (check1() and check2() and check3()):
    do_something()
于 2013-07-19T18:29:59.477 回答
1

我会说,如果检查不像这样微不足道(可以用一个简单and的 .

def doSomethingIfConditions():

  if not check1():
    return

  if not check2():
    return

  if not check3():
    return

  doSomething()

...your code...
doSomethingOnConditions()
...your code...
于 2013-07-19T18:32:25.270 回答
1
  if check1() and  check2() and  check3():  
         do_something()
于 2013-07-19T18:30:06.797 回答
0

我认为不需要循环......无论如何,你最终都会摆脱它。

if all((check1(), check2(), check3())):
    print "Do something"

或者,如果需要,只需使用块样式。

于 2013-07-19T18:41:21.787 回答
0

解决方案#1(直截了当):

while True:
    if not check1():
        break
    if not check2():
        break
    if not check3():
        break
    do_something()
    break

解决方案#2(更多pythonic):

for check in check1, check2, check3:
    if not check():
        break
else:
    # the else part is only executed
    # if we didn't break out the loop
    do_something()

解决方案#3(甚至更多pythonic):

if all(c() for c in check1,check2, check3):
    # all(seq) will stop at the first false result
    do_something()
于 2013-07-19T18:36:59.383 回答
-3

在 C 中,do ... while(0)当 C 程序员想要一些行为类似于 a 的东西时,通常会使用您展示的构造goto,但使用实际goto是不可能的(出于各种原因)。所以,breakout of thedo ... while(0)真的是一种hack。在 Python 中使用相同的习语会使这种黑客行为永久化。

在 C 语言中,我通常会避免使用 的这种特殊用法do ... while(0),而是选择检查函数。在 Python 中,这将是:

def do_checks():
    if not check1():
        return False
    if not check2():
        return False
    if not check3():
        return False
    return True

if do_checks():
    do_something()

可能对 C 结构最直接的翻译是do ... while(0)具有单次迭代的循环。不要这样做。

for x in range(1):
    if not check1():
        break
    if not check2():
        break
    if not check3():
        break
    do_something()
于 2013-07-19T18:31:34.273 回答