2009-08-21 3 views
56

Pythonのユーザー定義関数では何が良いのですか?例外を発生させるか、Noneを返しますか?たとえば、私はフォルダ内の最新のファイルを見つける関数を持っています。Python関数で例外を発生させずに返すなし

def latestpdf(folder): 
    # list the files and sort them 
    try: 
     latest = files[-1] 
    except IndexError: 
     # Folder is empty. 
     return None # One possibility 
     raise FileNotFoundError() # Alternative 
    else: 
     return somefunc(latest) # In my case, somefunc parses the filename 

別のオプションは、例外を残して、発信者のコードでそれを処理ですが、私はそれははIndexErrorよりFileNotFoundErrorに対処するために、より明確なの姿。それとも、別の名前で例外を再発行するのは悪いフォームですか?

+0

類似:http://stackoverflow.com/questions/1152541/is-it-better-to-use-exception-or-return-code-in-python – codeape

+2

私は強制的に例外を発生させるために傾いています呼び出し関数で例外を処理します。呼び出し側の関数で出力がNoneかどうかを忘れると、潜在的なバグが発生する可能性があります。 Noneを返した場合、呼び出し関数の次の行でAttributeErrorが発生することを願っています。しかし、返された値がディクショナリに追加され、100の関数呼び出しが別のソースファイルに追加された場合、AttributeErrorが発生します。 – IceArdor

+0

一般的に、私はまた、特別な意味を持つ値や、ある関数に対して複数のシグニチャを持つ値(文字列またはNoneを返す可能性がある)を避けることもできます。 – IceArdor

答えて

67

これは実際に意味論の問題です。 foo = latestpdf(d)の意味はですか?

は、何の最新のファイルがないことを完全に合理的ですか?それから必ず、Noneを返してください。

いつも最新のファイルが見つかると思われますか?例外を発生させます。そして、より適切な例外を再発生させても問題ありません。

これは任意のディレクトリに適用することになっていますちょうど一般的な機能である場合は、私がかつての操作を行うと、Noneを返したいです。ディレクトリが、例えば、アプリケーションの既知のファイルセットを含む特定のデータディレクトリであることを意図している場合、例外を発生させる。

+0

もうひとつ考慮すべき点:例外を発生させる場合は、メッセージを添付することができますが、「None」を返すときはそれを行うことはできません。 –

1

一般的には、何か壊滅的な事態が発生した場合(つまり、あなたの関数が接続できないインターネットリソースを扱う場合)に例外がスローされ、関数が実際に何かを返さなければなりませんが、返すのに適切なものは何もありません(つまり、関数が文字列中の部分文字列にマッチしようとすると "None"など)。

4

のpythonが動的型付けされたので、私は通常(すなわち、おそらくNoneを返さない、呼び出された関数の内部を除いて/してみてください)、内部例外を処理することを好みます。一般的に、私はそれ審判の判定一つの方法または他のを検討しますが、動的型付け言語では、呼び出し側に例外を渡していないの賛成でスケールを傾ける小さな要因がある:あなたを呼び出す

  1. 誰もが関数はスローされる例外を通知されません。それはあなたが狩りをしている例外の種類を知るための芸術形式のビットになります(そして、ブロックを避けるべきである一般的なブロックを除く)。
  2. if val is Noneexcept ComplicatedCustomExceptionThatHadToBeImportedFromSomeNameSpaceよりも少し簡単です。真剣に、私はfrom django.core.exceptions import ObjectDoesNotExistと入力することを忘れてはいけません。すべての私のdjangoファイルの一番上に、本当に一般的なユースケースを扱うだけです。静的に型指定された世界では、エディターがあなたのためにそれを行うようにしてください。

正直なところ、それは常に判断の呼び出しであり、呼び出された関数がエラーを受け取った場合には、それは意味のある例外を再発生させる優れた理由です。あなたは正確に正しい考えを持っていますが、例外はあなたが返す場合、発信者は何が表示されますされ、10のうち9回、

AttributeError: 'NoneType' object has no attribute 'foo' 

よりも、スタックトレースをより意味のある情報を提供しようとしているでない限り未処理なし、気にしないでください。

(これらのすべての種類のPython例外は、Javaの場合と同様に、デフォルトではcauseという属性を持っていて、新しい例外に例外を渡すことができます。問題。)

5

あなたの質問に答える前に、あなたの質問に答えるかもしれないので、私はいくつかの提案をします。

  • 機能には常に説明的な名前を付けます。 latestpdfは誰にもほとんど意味しませんが、あなたの機能を見てくださいlatestpdf()は最新のpdfを入手します。私はあなたがそれをgetLatestPdfFromFolder(folder)と名づけることを勧めます。

すぐに私はこれを返すべきものが明確になりました。もしpdfがなければ、例外が発生します。しかしもっと待ちます..

  • 機能を明確にしておいてください。 somefucがやろうとしていることは明らかではないので、最新のpdfの入手方法とは明らかに分かりません。これにより、コードがはるかに読みやすくなります。

for folder in folders: 
    try: 
     latest = getLatestPdfFromFolder(folder) 
     results = somefuc(latest) 
    except IOError: pass 

この情報がお役に立てば幸い!

関連する問題