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 ループを実装する方法を求めているわけではありませんが、前述のピラミッド スタイルのコードを回避する手法を求めています。

更新:混乱があるようです。私がループを使用している唯一の理由は、1 回だけ実行されるはずの本体の任意の場所で抜け出せるようにするためです。

基本的に私が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 に答える
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 に答える
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 に答える
0

ループの必要性はわかりません... とにかく最後にそれを抜け出します。

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

または、必要に応じてブロックスタイルを使用してください。

于 2013-07-19T18:41:21.787 に答える
-3

Cでは、do ... while(0)あなたが示した構造の使用は通常、Cプログラマーが のように動作するものが必要な場合に使用されますがgoto、実際の使用gotoは(さまざまな理由で)問題外です。だから、breakアウトdo ... while(0)オブザは本当に一種のハックです。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)、1 回の反復によるループです。これをしないでください。

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 に答える