「a == x or y or z」の謎を明らかにする: なぜ常に True と評価されるのか
Python では、ユビキタスな「a == x または y または z」の比較は、繰り返し起こる混乱の原因です。一見簡単そうに見えますが、特にセキュリティ アプリケーションでは予期せぬ結果を招く可能性があります。
問題:
承認されたユーザーにアクセスを許可することを目的とした次のコードを考えてみましょう。
name = input("Hello. Please enter your name: ") if name == "Kevin" or "Jon" or "Inbar": print("Access granted.") else: print("Access denied.")
驚くべきことに、このコードは、権限のないユーザーに次のようなアクセスを許可します。
解決策: 構文の解読
問題は、「or」演算子の解釈にあります。 Python では、この演算子はブール代数の規則に従います。したがって、「a == x or y or z」は次の式と同等です:
(a == x) or (y) or (z)
「Bob」のようなユーザーがアクセス権を取得しようとすると、式は次のように評価されます:
(False) or ("Jon") or ("Inbar")
ブール代数によれば、「or」演算子は最初に見つかった真の値を返します。この場合、「Jon」は真実であるため、式が true と評価され、権限のないユーザーにアクセスが許可されます。
適切な条件構造
この落とし穴を回避するには、次のようにします。条件文を正しく記述するには、主に 3 つの方法があります。ステートメント:
複数の == 演算子:
if name == "Kevin" or name == "Jon" or name == "Inbar": ...
メンバーシップ内演算子:
if name in {"Kevin", "Jon", "Inbar"}: ...
any() とジェネレータ式:
if any(name == auth for auth in ["Kevin", "Jon", "Inbar"]): ...
パフォーマンス考慮事項
一般に読みやすさと速度の観点から in 演算子が好まれますが、パフォーマンスの比較は次のとおりです。
name = "Inbar" >>> timeit.timeit("name == \"Kevin\" or name == \"Jon\" or name == \"Inbar\"", ... setup="name=\"Inbar\"") 0.0960568820592016 >>> timeit.timeit("name in {\"Kevin\", \"Jon\", \"Inbar\"}", setup="name=\"Inbar\"") 0.034957461059093475 >>> timeit.timeit("any(name == auth for auth in [\"Kevin\", \"Jon\", \"Inbar\"])", ... setup="name=\"Inbar\"") 0.6511583919636905
結論
理解「a == x or y or z」の微妙なニュアンスは、Python で効果的な条件文、特に関連する条件文を書くために重要です。アクセス制御に。正確で安全なコードを確保するには、ここで説明する代替構造を必ず使用してください。
以上がPython で「a == x or y or z」が常に True と評価されるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。