2017-12-12 11 views
0

部品コードのどれが合理的か論理的か?
パート1:定義メソッドまたは呼び出しメソッドでtry/catchを使用しますか?

def foo(): 
    try: 
     pass # some process 
    except Exception as e: 
     print(e) 
foo() 

はパート2:

def foo(): 
    pass # some process 
try: 
    foo() 
except Exception as e: 
    print(e) 
+1

私はそれが 'foo()'と '#何らかのプロセス 'に依存していると言いたいでしょう。それはあなた自身の個人的なコーディングスタイルに単純に帰着しますが、非常にうまくいくかもしれません。 –

+0

@ Ev.Kounisこれらの部分の違いは本当に(さまざまなケースで)違いますか? –

答えて

5

それは何をするかfooに依存し、Exceptionの種類、私が言うと思います。

発信者がそれを処理する必要がありますか?例えば

、次の例を考えてみます。

def try_get_value(registry, key): 
    try: 
     return registry[key] 
    except KeyError: 
     return None 

この関数は、そのキーを使用して辞書から値を取得しようとします。値が存在しない場合は、Noneを返します。

この場合、KeyErrorを処理する必要があります。これは、予想される動作に準拠するために、Noneを返す必要があるためです。 (それは、このエラーキャッチする方法のresponsabilityです)

をしかし、他の例外タイプを考える、などTypeError例えば、レジ​​ストリはdictない場合)。

なぜ私たちの方法でそれを処理すべきですか?それは呼び出し元の混乱です。彼はそれを処理する必要があり、彼はそれについて心配する必要があります。

さらに、もし私たちがこのようなことをすれば私たちの方法はできますか?Exception?この範囲からそれを処理する方法はありません。

try_get_valueには1つの簡単なタスクがあります:レジストリから値を取得する(存在しない場合はデフォルトの値)。呼び出し元がルールを破棄する責任はありません。

したがってではないため、TypeErrorをキャッチしません。

したがって、呼び出し側のコードは次のようなもののように見えることがあります。

try: 
    value = try_get_value(reg, 'some_key') 
    # Handle value 
except TypeError: 
    # reg is not a dict, do something about it... 

P.S.:私たちのfooメソッドが予期せぬ終了(など)でクリーンアップを行う必要がある場合があります。たとえば、閉じていないとリークするリソースが割り当てられています。

この場合、fooは例外をキャッチする必要があります。したがって、その状態を適切に修正できるはずですが、raiseを再度呼び出し元に戻す必要があります。

2

私は最初の部分はよりクリーンでよりエレガントだと思います。また、関数の実装者として、クライアントまたは呼び出し元に任せずにスローする可能性があるすべての例外を処理する必要があるため、より論理的です。このメソッドを使用する唯一のメソッドであっても、将来は例外がどのような例外をスローしているのかを覚えていない可能性があります。

+0

これはdocstringが便利な場所です。それは、関数が受け入れる入力パラメータ、型を返すこと、およびドキュメンテーションに従った場合の動作や効果を明確に文書化します。 docstringsの詳細については、https://www.python.org/dev/peps/pep-0257/ –

関連する問題