揭开“a == x or y or z”的神秘面纱:为什么它总是计算为 True
在 Python 中,无处不在的“a == x or y or 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")
根据布尔代数,“或”运算符返回遇到的第一个真值。在本例中,“Jon”为真,导致表达式计算为 true 并授予未经授权的用户访问权限。
正确的条件构造
要避免此陷阱,正确编写条件语句有以下三种主要方法语句:
多个 == 运算符:
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中文网其他相关文章!