11

Pythonの声明に関する質問への(S.Lottによる)回答では:try...else

実際、if ステートメントでも、else: は非常にひどい方法で悪用され、見つけるのが非常に困難なバグを作成する可能性があります。[...]

他についてよく考えてください。それは一般的に問題です。if ステートメント以外では避けてください。その場合でも、else 条件を文書化して明示的にすることを検討してください。

これは広く受け入れられている意見ですか?else 有害と見なされますか?

もちろん、紛らわしいコードを書くこともできますが、それは他の言語構造にも当てはまります。Python でさえfor...else、持っていると非常に便利なもののように思えます (あまりそうではありませんtry...else)。

4

13 に答える 13

7

それ以外が有害であると言うのは、変数やクラスが有害であると言うのと少し似ています。まったく、goto は有害だと言っているようなものです。確かに、物事は悪用される可能性があります。しかし、ある時点で、プログラマーが大人であり、そうではないほど頭が良いことを信頼する必要があります。

つまり、SO の回答、ブログ投稿、または Dijkstra の有名な論文でさえ、何かを使用しないことを望んでいる場合は、プログラミングが自分にとって適切な職業であるかどうかを検討する必要があります。 .

于 2009-05-14T21:09:25.370 に答える
7

害があるとは言いませんが、else ステートメントで問題が発生する場合があります。たとえば、入力値に基づいて何らかの処理を行う必要があり、有効な入力値が 2 つしかない場合です。1 つだけをチェックすると、バグが発生する可能性があります。例えば:

The only valid inputs are 1 and 2:

if(input == 1)
{
   //do processing
   ...
}
else
{
   //do processing 
   ...
}

この場合、else を使用すると、値 1 と 2 のみを処理する必要があるときに、1 以外のすべての値を処理できます。

于 2009-05-14T21:09:31.220 に答える
6

私にとって、特定の一般的な言語構造が本質的に悪いという概念全体は、まったく間違っています。gotoその場所さえあります。Walter Bright や Linus Torvalds などによる、非常に読みやすく保守しやすいコードを使用しているのを見てきました。特定の構造を「有害」と恣意的に宣言するよりも、読みやすさが重要であることをプログラマーに教え、常識を使用する方がはるかに優れています。

于 2009-05-14T21:08:48.227 に答える
3

Elseは、コードに関する仮定を文書化するときに最も役立ちます。これにより、if ステートメントの両側を熟考したことが保証されます。

各 if ステートメントで常に else 句を使用することは、「Code Complete」でも推奨される方法です。

于 2009-05-14T21:11:31.620 に答える
3

逆に...私の意見では、すべてのifにはelseが必要です。確かに、あなたはばかげたことをすることができますが、十分に努力すれば、あらゆる構造を悪用することができます. 「本物のプログラマーはあらゆる言語で FORTRAN を書ける」ということわざをご存知でしょう。

私が頻繁に行っているのは、else 部分をコメントとして記述し、何もすることがない理由を説明することです。

于 2009-05-14T21:12:24.443 に答える
2

そもそも Python にelseステートメント (of )を含める理由は、本当に必要な例外だけをキャッチすることでした。try...else通常、try...exceptブロックがある場合、例外を発生させる可能性のあるコードがいくつかあり、前のコードが成功した場合にのみ実行するコードがさらにいくつかあります。ブロックがなければ、すべてのコードをブロックelseに入れる必要があります。try

try:
    something_that_might_raise_error()
    do_this_only_if_that_was_ok()
except ValueError:
    # whatever

問題は、 ? が発生した場合はどうdo_this_only_if_that_was_ok()なるValueErrorかです。exceptあなたがそれを望んでいないかもしれないときに、それはステートメントに引っかかるでしょう。elseそれがブロックの目的です。

try:
    something_that_might_raise_error()
except ValueError:
    # whatever
else:
    do_this_only_if_that_was_ok()

ある程度は意見の問題だと思いますが、私はめったに使用しませんが、個人的にはこれは素晴らしいアイデアだと思います。実際に使用すると、非常に適切だと感じます (さらに、コード フローを少し明確にするのに役立つと思います)。

于 2009-05-14T21:12:23.227 に答える
1

次のようにCファミリ言語で発生する、いわゆる「ぶら下がりelse」問題があります。

if (a==4)
if (b==2)
printf("here!");
else
printf("which one");

この純真なコードは、次の2つの方法で理解できます。

if (a==4)
    if (b==2)
        printf("here!");
    else
        printf("which one");

また

if (a==4)
    if (b==2)
        printf("here!");
else
    printf("which one");

問題は、「else」が「dangling」であり、他の所有者を混乱させる可能性があることです。もちろん、コンパイラはこの混乱を引き起こしませんが、それは人間には有効です。

Pythonのおかげで、Pythonで他の問題が発生することはありません。これは、どちらかを記述しなければならないためです。

if a==4:
    if b==2:
        print "here!"
else:
    print "which one"

また

if a==4:
    if b==2:
        print "here!"
    else:
        print "which one"

人間の目がそれを捕らえるように。そして、いや、「else」は有害だとは思いません。「if」と同じくらい有害です。

于 2009-05-15T22:11:10.813 に答える
1

デフォルトのシナリオまたは副作用がある言語およびフロー制御ステートメントについては、そのシナリオを同じレベルで考慮する必要があるように思えます。if または switch または while のロジックは、条件 if(x) while(x) または for(...) と同じくらい適切です。したがって、ステートメントは有害ではありませんが、その条件のロジックは有害です。

したがって、開発者として、else の広い範囲を念頭に置いてコーディングすることは私たちの責任です。あまりにも多くの開発者がそれを「上記ではない場合」として扱いますが、実際にはすべての常識を無視できます。これは、その中の唯一のロジックが前のロジックの否定であり、多くの場合不完全であるためです。(アルゴリズム設計ミスそのもの)

私は、「else」が for() ループでの off-by-ones や不適切なメモリ管理よりも有害であるとは考えていません。それはすべてアルゴリズムに関するものです。オートマトンの範囲と可能な分岐が完全であり、すべてが具体的で理解されている場合、危険はありません。危険なのは、広い範囲のロジックの影響を理解していない人々による、式の背後にあるロジックの誤用です。コンピューターは愚かで、オペレーターから言われたことを実行します(理論上)

未知の量のコードへの処理を無効にする可能性があるため、トライアンドキャッチは危険であると考えています。レイズの上の分岐にはバグが含まれている可能性があり、レイズ自体によって強調されます。これは自明ではない可能性があります。これは、一連の命令をエラー処理のツリーまたはグラフに変換するようなもので、各コンポーネントは親の分岐に依存しています。奇数。私はCが大好きです。

于 2009-05-14T21:12:52.617 に答える
0

推論が難しいとされる例では、明示的に記述できますが、else は依然として必要です。例えば

if a < 10:       
    # condition stated explicitly   
elif a > 10 and b < 10:       
    # condition confusing but at least explicit   
else:       
    # Exactly what is true here?       
    # Can be hard to reason out what condition is true

書き込み可能

if a < 10:       
    # condition stated explicitly   
elif a > 10 and b < 10:       
    # condition confusing but at least explicit   
elif a > 10 and b >=10:
    # else condition
else:   
    # Handle edge case with error?
于 2009-05-14T21:11:30.327 に答える
0

に関するポイントは、それを修正するのではなく、矛盾した状態を作成するためtry...except...elseに使用するのは簡単な間違いだと思います. 絶対に避けるべきというわけではありませんが、逆効果になる可能性があります。

検討:

try:
    file = open('somefile','r')
except IOError:
    logger.error("File not found!")
else:
    # Some file operations
    file.close()
# Some code that no longer explicitly references 'file'

上記のブロックにより、コードが存在しないファイルやユーザーがアクセス許可を持っていないディレクトリにアクセスしようとするのを防ぎ、try...except...elseブロック内にあるためすべてがカプセル化されていると言えます。しかし実際には、上記の形式の多くのコードは次のようになります。

try:
    file = open('somefile','r')
except IOError:
    logger.error("File not found!")
    return False
# Some file operations
file.close()
# Some code that no longer explicitly references 'file'

fileはスコープ内で参照されなくなったので、ブロックの後にコーディングを続けても問題ないが、多くの場合、問題が発生する可能性があると言って、自分をだますことがよくあります。または、ブロック内で作成されていない変数が後でelseブロック内で作成される可能性がありexceptます。

これが と を区別する方法if...elseですtry...except...else。どちらの場合も、ほとんどの場合、ブロックを並列にする必要があります (一方に設定された変数と状態は、もう一方に設定する必要があります) が、後者の場合、おそらく不可能または無関係であるため、コーダーはそうしません。このような場合、最良のシナリオであると思われるものに対処し続けるよりも、呼び出し元に戻る方がはるかに理にかなっていることがよくあります。

于 2009-05-14T21:50:38.703 に答える