为什么`a == b或c或d`总是评估为True?我正在编写一个拒绝访问未授权用户的安全系统。import sysprint("Hello. Please enter your name:")name = sys.stdin.readline().strip()if name == "Kevin" or "Jon" or "Inbar":
print("Access granted.")else:
print("Access denied.")它按预期授予对授权用户的访问权限,但它也允许未经授权的用户访问!Hello. Please enter your name:
Bob
Access granted.为什么会这样?我明确表示,只有在与nameKevin,Jon或Inbar相同时才授予访问权限。我也尝试过相反的逻辑if "Kevin" or "Jon" or "Inbar" == name,但结果是一样的。
2 回答
互换的青春
TA贡献1797条经验 获得超6个赞
在许多情况下,Python的外观和行为与自然英语相似,但这是抽象失败的一种情况。人们可以使用上下文线索来确定“Jon”和“Inbar”是加入动词“equals”的对象,但Python解释器更具有文字意识。
if name == "Kevin" or "Jon" or "Inbar":
在逻辑上等同于:
if (name == "Kevin") or ("Jon") or ("Inbar"):
对于用户Bob来说,相当于:
if (False) or ("Jon") or ("Inbar"):
该or
运营商选择以积极的第一个参数真值:
if ("Jon"):
由于“Jon”具有正的真值,因此该if
块执行。这就是导致“授予访问权限”被打印的原因,无论给出的名称如何。
所有这些推理也适用于表达式if "Kevin" or "Jon" or "Inbar" == name
。第一个值为"Kevin"
true,因此if
块执行。
有两种常用方法可以正确构建此条件。
使用多个
==
运算符显式检查每个值:if name == "Kevin" or name == "Jon" or name == "Inbar":
编写一系列有效值,并使用
in
运算符测试成员资格:if name in ("Kevin", "Jon", "Inbar"):
一般来说,第二个应该是首选,因为它更容易阅读,也更快:
In [1]: name = "Inbar"In [2]: %timeit name == "Kevin" or name == "Jon" or name == "Inbar"10000000 loops, best of 3: 116 ns per loopIn [3]: %timeit name in ("Kevin", "Jon", "Inbar")10000000 loops, best of 3: 65.2 ns per loop
qq_笑_17
TA贡献1818条经验 获得超7个赞
简单的工程问题,让我们更进一步。
In [1]: a,b,c,d=1,2,3,4In [2]: a==bOut[2]: False
但是,继承自语言C,Python将非零整数的逻辑值评估为True。
In [11]: if 3: ...: print ("yey") ...:yey
现在,Python构建在该逻辑上,并允许您使用逻辑文字,例如或整数,等等
In [9]: False or 3Out[9]: 3
最后
In [4]: a==b or c or dOut[4]: 3
写它的正确方法是:
In [13]: if a in (b,c,d): ...: print('Access granted')
为安全起见,我还建议您不要硬编码密码。
添加回答
举报
0/150
提交
取消