4

その構造の長い Python 関数があります。

def the_function(lots, of, arguments):

    return_value = None

    if some_important_condition:

        # a lot of stuff here

        return_value = "some value"

    else:

        # even more stuff here

        return_value = "some other value"

    return return_value

if問題の 1 つは、とブロックの両方にelse1 画面分以上のコードが含まれていることです。インデントを見失ったり、現在の状態を確認するために上にスクロールしなければならなくなったりするのは簡単です。

これを改善する 1 つのアイデアは、いくつかの関数に分割することです。

def case_true(lots, of, arguments):

    # a lot of stuff here

    return "some value"

def case_false(lots, of, arguments):

    # even more stuff here

    return "some other value"

def the_function(lots, of, arguments):

    return_value = None

    if some_important_condition:

        return_value = case_true(lots, of, arguments)

    else:

        return_value = case_false(lots, of, arguments)

    return return_value

しかし、議論のジャグリングを考えると、これで問題が解決するかどうかはわかりません。

別のアイデアは、複数の出口点を使用することです。

def the_function(lots, of, arguments):

    if some_important_condition:

        # a lot of stuff here

        return "some value"

    # even more stuff here

    return "some other value"

しかし、いくつかのコーディング スタイルは、複数の出口点に対して、特に画面が離れている場合にアドバイスしています。

問題は、元の構成をより読みやすく、保守しやすくするための、Python的な好ましい方法は何でしょうか?

4

2 に答える 2

5

関数内に複数の出口点を持つことはまったく問題ありません。単一の出口点のみの要件は古い慣例であり、プログラミング言語に例外処理がなく、単一の出口点を持つことが理にかなっていた時代にまでさかのぼります。エラー処理を集中化します。例外の存在により、その古い慣習は時代遅れになります。

単一関数の終了点ポリシーを適用する場合でも、複数の終了点を持つことが望ましい状況があります。関数の大部分は明らかに不適切です」、この場合、「意味のある作業が完了する前に、トップで救済することは非常に理にかなっています。そうしないと、関数の大部分をカバーする巨大な if ステートメントが必要になります。さらに別のレベルのインデント」.

完全を期すために、ここに私の要点を拡張した説明があります。

于 2013-03-05T17:27:56.120 に答える
2

黄金律は次のとおりです。1つの関数に複数の戻り点を含めることができますが、読みやすさを向上させる限り、コードが非常に大きい場合は、返すことと、次のような変数にコピーすることの間に違いはありません。戻ってきた。

あなたの問題は、あなたのルーチンのデザイン、抽象化のレベル、そしてセマ​​ンティクスに関するものだと思います。

これらの質問はあなたを助けるかもしれません:

  • ルーチンには機能的なまとまりがありますか?すなわち:それはただ一つのことをします。収入を計算し、印刷し、サーバーに送信して、犬と一緒に散歩するようなものではありません。

  • 関数には7つ以上の引数がありますか?もしそうなら、おそらくあなたのルーチンの抽象化のレベルは適切ではありません。

ルーチンの詳細(実行内容、返される内容、引数)についてもう少し情報を投稿すると役立ちます。そのために2つのクラスを使用する方が良いかもしれません...

しかし、一般的な答えとしては、個々のアクションを分析し、それらをまとまりのある小さな関数で因数分解し、関数を機能させるのではなく、これらの小さな関数の順次呼び出し元に変換する方がよいと思います。また、case_trueとcase_falseの関数が2つしかないというアプローチは、おそらく間違っています。両方の関数(trueとfalse)で同様のアクションがあり、それらを2回コーディングしている可能性が非常に高いためです。

于 2013-03-05T18:40:07.697 に答える