2

関数から忘れることreturn resultがあります:

def f(*args):
  # do stuff
  result = # an expression
  # oops forgot to return result

私のアプリケーションでは有効な値であるためNone、呼び出し元で例外やアラームさえも発生しません。もちろん、気をつけようと思います。しかし、明示的に値を返さない関数について警告するためのきちんとしたアプローチがあるかどうか疑問に思っていました。

おそらく、そのようなケースを見つけるためにコードを実行できる正規表現です。または、何らかのコード チェック ツール (Windows 環境で使用できることを願っています)。

私はこのようなデコレータを使用することさえ考えていました:

def requires_return(func):
  def new_func(*args, **kwargs):
    result = func(*args, **kwargs)
    if result is None:
      print('Warning: {} may be missing a return statement'.format(func.__name__))
    return result

しかし、これは次の理由で機能しません。

  1. 多くの誤報: 関数が実際に を返すたびにNoneNone他の場所で本当に醜いコードを作成せずに、アプリケーションでの使用をやめることはできません。

  2. いずれにせよ、すべての関数にデコレータを追加するのは非常に見苦しく思えます。

return意図的にステートメントを持たない関数があることに注意してください。私は特定の命名規則を維持する傾向があるため、それらを簡単に区別できます。(具体的には、で始まるすべての関数にget_は return ステートメントが必要です。)

4

4 に答える 4

4

簡潔な答え

一言で言えば、 unittestです。

これは、製品コードで解決しようとするべき問題ではありません。適切な一連のテストが問題を解決します。

単体テスト 101

単体テストとは API をテストすることであることに注意してください。

実際のコードの前にテストを書く慣行であるTDD (テスト駆動開発)と呼ばれるものもあります。したがって、プログラマーは存在しないコードの一部のテストを作成します。テストは明らかに失敗し、プログラマーは製品コードに移動し、関数を記述し、テストを実行します。テストが成功した場合、彼は次に進みます。

テストを書く習慣を身につけるのは、最初は少し大変ですが、本当に効果があります。

ここで単体テストを行う理由

適切な一連のテストでリターンを見逃す可能性があることがわかりません。

None私のアプリケーションでは有効な値であるため、呼び出し元で例外やアラームが発生することはありません。」

返さNoneれることは、API を壊すことです。単体テストは、これに対する正確な解決策です。

このバグを防ぐには?

このバグを防ぐ方法はTDDを使用することです。

最初にテストを作成すれば、バグになる前にこのバグを 99.9% 確実にキャッチできます。

注:これがあなたが探していた答えではないことはわかっていますが、ここでは単体テストが適切なツールです。変数を使用しresultたり、すべての関数にデコレータをアタッチしたりしても、問題は解決しません。

于 2012-04-08T23:33:16.063 に答える
4

する習慣をつけないことをお勧めします

def something():
    ...
    result = ...
    return result

代わりに次のようにします。

def something():
    ...
    return ...

それ以外では、Noneデフォルトで戻ることは 99% の確率で便利な機能です。

于 2012-04-08T22:51:25.300 に答える
3

Pylint は、この種のエラーをキャッチすることがあります。特に、割り当ててresultも使用しない場合:

pylint zorg.py
************* Module zorg
W0612:  5:zorg: Unused variable 'result'

ただし、バラバラに積み上げてから返すのを忘れた場合はキャッチしませんresult(変数が「未使用」ではないため)。

ただし、他の多くのことに応じて、pylint は静的な型分析を通じて、値を返すのに失敗したことをキャッチする場合があります。

于 2012-04-08T22:58:20.037 に答える
0

治療するよりも予防​​する方が良いです。つまり、必要に応じて値を返す習慣を身につける必要があります。return statementの代わりに直接使用することもできますresult = statement; return result

于 2012-04-08T22:52:35.417 に答える