web-dev-qa-db-ja.com

return、return none、およびno returnはまったくありませんか。

3つの機能を考えます。

def my_func1():
  print "Hello World"
  return None

def my_func2():
  print "Hello World"
  return

def my_func3():
  print "Hello World"

それらはすべてNoneを返すようです。これらの関数の戻り値の振る舞いに違いはありますか?一方を他方よりも優先する理由はありますか?

310
Clay Wardell

実際の動作上、違いはありません。それらはすべてNoneを返し、それだけです。しかし、これらすべてに時間と場所があります。以下の説明は基本的にどのように異なる方法を使うべきか(または少なくとも私がどのように使うべきか教えられたか)ですが、それらは絶対的な規則ではないので必要に応じて混同できます。

return Noneを使う

これは、この関数が実際に後で使用するために値を返すことを意図していることを示しており、この場合はNoneを返します。この値Noneは他の場所で使用できます。関数から他に返される可能性のある値がない場合、return Noneは使用されません。

次の例では、指定されたpersonが人間の場合、motherpersonを返します。それが人間ではない場合、Nonepersonを持たないのでmotherを返します(動物ではないと仮定しましょう)。

def get_mother(person):
    if is_human(person):
        return person.mother
    else:
        return None

returnを使う

これは、ループ内のbreakと同じ理由で使用されます。戻り値は問題ではなく、関数全体を終了したいだけです。それはあなたがそんなに頻繁にそれを必要としないとしても、それはいくつかの場所で非常に役に立ちます。

私たちは15のprisonersを手に入れましたが、そのうちの一つにナイフがあります。それぞれのprisonerを1つずつループ処理して、ナイフがあるかどうかを確認します。人をナイフで叩いた場合、関数を終了することができます。ナイフが1つしかなく、prisonersの残りの部分をチェックする理由はありません。ナイフでprisonerが見つからない場合は、警告が出されます。これはさまざまな方法で行うことができ、returnを使用することはおそらく最善の方法でさえありませんが、関数を終了するためのreturnの使用方法を示す例にすぎません。

def find_prisoner_with_knife(prisoners):
    for prisoner in prisoners:
        if "knife" in prisoner.items:
            prisoner.move_to_inquisition()
            return # no need to check rest of the prisoners nor raise an alert
    raise_alert()

注意:戻り値は捕捉されることを意図していないので、決してvar = find_prisoner_with_knife()をしてはいけません。

まったくreturnを使用しない

これはNoneも返しますが、その値は使われることも捕らえられることも意図されていません。それは単に機能が正常に終了したことを意味します。基本的にはC++やJavaなどの言語のreturn関数のvoidと同じです。

次の例では、人の母親の名前を設定して、関数は正常に完了した後に終了します。

def set_mother(person, mother):
    if is_human(person):
        person.mother = mother

注意:戻り値は捕捉されることを意図していないので、決してvar = set_mother(my_person, my_mother)をしてはいけません。

408
user2032433

はい、それらはすべて同じです。

解釈されたマシンコードをレビューして、それらがすべてまったく同じことをしていることを確認できます。

import dis

def f1():
  print "Hello World"
  return None

def f2():
  print "Hello World"
  return

def f3():
  print "Hello World"

dis.dis(f1)
    4   0 LOAD_CONST    1 ('Hello World')
        3 PRINT_ITEM
        4 PRINT_NEWLINE

    5   5 LOAD_CONST    0 (None)
        8 RETURN_VALUE

dis.dis(f2)
    9   0 LOAD_CONST    1 ('Hello World')
        3 PRINT_ITEM
        4 PRINT_NEWLINE

    10  5 LOAD_CONST    0 (None)
        8 RETURN_VALUE

dis.dis(f3)
    14  0 LOAD_CONST    1 ('Hello World')
        3 PRINT_ITEM
        4 PRINT_NEWLINE            
        5 LOAD_CONST    0 (None)
        8 RETURN_VALUE      
26
David Marx

それらはそれぞれ同じシングルトンNoneを返します - 機能的な違いはありません。

早めに関数から抜け出す必要がある場合(そうでない場合はreturnがより一般的です)、return以外のものを返す必要がある場合を除き、Noneステートメントを省略することは合理的に意味があると思います。 None以外の何かを返す別のパスを持つ関数内にある場合、return Noneを書くのも理にかなっており、慣用的なようです。明示的にreturn Noneを書くことは、もっと面白いことを返す別のブランチがあることを読者に視覚的に知らせるものです(そして呼び出しコードはおそらく両方のタイプの戻り値を処理する必要があるでしょう)。

Pythonでは多くの場合、Noneを返す関数はCのvoid関数のように使用されます - それらの目的は一般に入力引数in placeを操作することです(グローバルデータを使用しているのでない限り(shudders) _))。 Noneを返すと、通常、引数が変更されたことがより明確になります。これにより、「言語規約」の観点からreturnステートメントを省略するのが理にかなっている理由がもう少し明確になります。

そうは言っても、あなたがすでにこれらの事柄に関して予め設定された規約を持っているコードベースで作業しているなら、私は間違いなくコードベースが統一されるのを助けるためにスーツに従うと思います...

18
mgilson

機能的にはこれらはすべて同じですが、両者の違いはコードの読みやすさとスタイルにあります(考慮することが重要です)。

2
Yehuda Schwartz