web-dev-qa-db-ja.com

PythonのEAFP原則とは何ですか?

Pythonで「EAFPの原則を使用する」とはどういう意味ですか?例を挙げていただけますか?

115
Unpaid Oracles

用語集 から:

許可よりも許しを求める方が簡単です。この一般的なPythonコーディングスタイルは、有効なキーまたは属性の存在を前提とし、仮定が偽である場合に例外をキャッチします。このクリーンで高速なスタイルは、多くのtryexceptステートメント:この手法は、Cなどの他の多くの言語に共通の LBYLスタイル とは対照的です。

例としては、ディクショナリキーにアクセスする試みがあります。

EAFP:

try:
    x = my_dict["key"]
except KeyError:
    # handle missing key

LBYL:

if "key" in my_dict:
    x = my_dict["key"]
else:
    # handle missing key

LBYLバージョンは、ディクショナリ内のキーを2回検索する必要があり、少し読みにくいと見なされる場合もあります。

189
Sven Marnach

別の例を使用して説明します。

ここでは、ファイルにアクセスし、コンソールでコンテンツを印刷しようとしています。

LBYL-飛ぶ前に見てください:

ファイルにアクセスできるかどうかを確認します。アクセスできる場合は、ファイルを開いて内容を印刷します。ファイルにアクセスできない場合は、else部分をヒットします。これが競合状態である理由は、最初にアクセスチェックを行うためです。 with open(my_file) as f:に達するまでに、アクセス許可の問題のためにアクセスできなくなる可能性があります(たとえば、別のプロセスが排他的なファイルロックを取得します)。このコードはエラーをスローする可能性が高く、ファイルにアクセスできると考えたため、そのエラーをキャッチすることはできません。

import os

my_file = "/path/to/my/file.txt"

# Race condition
if os.access(my_file, os.R_OK):
    with open(my_file) as f:
        print(f.read())
else:
    print("File can't be accessed")

EAFP-許可よりも許しを求める方が簡単:

この例では、ファイルを開こうとしているだけで、開くことができない場合はIOErrorをスローします。可能であれば、ファイルを開いて内容を印刷します。そのため、求める代わりに試行を実行します。それがうまくいけば、素晴らしい!そうでない場合は、エラーをキャッチして処理します。

# # No race condition
try:
    f = open(my_file)
except IOError as e:
    print("File can't be accessed")
else:
    with f:
        print(f.read())
5
Apoorv Patne

私はそれを「楽観的プログラミング」と呼んでいます。ほとんどの場合、人々は正しいことを行い、エラーは少ないはずです。そのため、最初に「正しいこと」が発生するようにコーディングし、発生しない場合はエラーをキャッチします。

私の気持ちは、ユーザーが間違いを犯そうとしている場合、時間の影響を被るのはユーザーでなければならないということです。正しい方法でツールを使用する人々はスピードアップします。

5
Engineer