web-dev-qa-db-ja.com

「return None」をスキップしても大丈夫ですか?

return Noneを必要としないときにスキップするのは悪いやり方かしら。

例:

def foo1(x):
    if [some condition]:
        return Baz(x)
    else:
        return None

def foo2(x):
    if [some condition]:
        return Baz(x)

bar1 = foo1(x)
bar2 = foo2(x)

どちらの場合も、条件がfalseの場合、関数はNoneで戻ります。

43
Tomasz Wysocki

あなたが言ったように、return Noneは(ほとんど)必要ありません。

しかし、明示的なreturn Noneを使用すると、コードのintentionがより明確になることを考慮する必要があります。覚えておいてください。コードの一部も人間が読めるようにする必要があり、通常は明示的にすることが役立ちます。

62
rsenna

他の人が言ったことを詳しく説明するために、私はreturn None関数が値を返すことになっている場合。 Pythonでは、すべての関数が値を返しますが、戻り値が無視されるため、Noneのみを返す関数を記述することがよくあります。一部の言語では、これらはプロシージャと呼ばれます。

したがって、関数が値を返すことになっている場合は、すべてのコードパスに戻りがあること、および戻り値がNoneであっても戻り値があることを確認します。

関数が値を「返さない」場合、つまり、戻り値を使用して誰かから呼び出されない場合は、リターンなしで終了してもかまいません。早期に戻る必要がある場合は、ベアフォームを使用します。 return

25
Ned Batchelder

はいといいえ。

最も単純なケースでは、スキップしても問題ありません "Noneを返す"は、単一の負の条件でのみNoneを返すためです。

ただし、ネストされた条件評価と、関数がNoneを返す可能性のある複数のシナリオがある場合。私はそれらをシナリオのビジュアルドキュメントとして含める傾向があります。

[編集:以下のコメントに基づく]

リターンまたはリターンなし

裸の "return"よりも "return None"を好む明示的であり、後で、戻り値がNoneを返すことを意味するのか、何かが欠落しているためにエラーであるのかを疑う人はいません。

5
pyfunc

はい、Python関数から値を返さない場合は、Noneを返します。したがって、Noneを明示的に返すかどうかは、スタイルの決定です。

個人的には、わかりやすくするために常に値を返すことを好みます。

3
JAL

あなたがそれについて考えれば考えるほど、あなたが説明するケースが良い実践を示しているとは思いません。それはクライアントを区別することを強制するので、クライアントコードはほとんど常に次のようになります:

b = foo1(123)
if b is not None:
    ...

あなたも書くことができませんでした:

if b:
    ...

以来、Baz.__nonzero__は上書きされ、NoneでなくてもbはFalseと評価されます。 Null-Bazインスタンス(AKA Null Object )、例:

class Baz(object):
    def some_method(self):
        """some action:"""
        ...
    ...

class BazNull(Baz):
    def some_method(self):
        """nothing happens here"""
    ...

Baz.Null = BazNull()

...

def foo1(x):
    if some_condition:
        return Baz(x)
    else:
        return Baz.Null

...

b = foo1(123)
b.some_method()

重要なのは、クライアント(自分自身かもしれない!)が Cyclomatic Complexity を低く保つのを助けることです。ブランチが少ないほど良いです。

1
pillmuncher
def foo1(x):
    try:
        return Baz(x)
    except:
        raise ValueError('Incorrect value fo Bac')

または

def foo3(x):
    return Baz(x) if <condition> else False

私は半分定義された関数を信じていませんが、このFalseは検索タイプの失敗のプルーニングに役立ちます。

0

私はここでの答えの多くに同意しません。
明示的なものは暗黙的なものより優れていますが、読みやすさに関しては、少ない方が多い場合があります。

def get_cat():
    if cat_is_alive():
        return Cat()
# vs     

def get_cat():
    if cat_is_alive():
        return Cat()
    return None

この特定の例では、すべての関数がデフォルトでNoneを返すため、実際には有益な情報を提供しない2行が追加されています。

さらに、型ヒントを使用すると、return Noneの明示性がさらに失われます。

def get_cat() -> Union[Cat, None]:
    if cat_is_alive():
        return Cat()

return Noneを含めると、二重の冗長性があります。デフォルトではNoneが返され、タイプヒントマークアップで明示的に示されます。

Imhoはreturn Noneを追跡しないでください。これらは完全に無意味で醜いです。

0
Granitosaurus