为什么`a == b或c或d`总是评估为True?

为什么`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,但结果是一样的。


一只萌萌小番薯
浏览 880回答 2
2回答

互换的青春

在许多情况下,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

简单的工程问题,让我们更进一步。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')为安全起见,我还建议您不要硬编码密码。
打开App,查看更多内容
随时随地看视频慕课网APP