为了账号安全,请及时绑定邮箱和手机立即绑定

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

/ 猿问

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

一只萌萌小番薯 2019-05-23 11:04:32

为什么`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 回答

?
互换的青春

在许多情况下,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块执行。


有两种常用方法可以正确构建此条件。

  1. 使用多个==运算符显式检查每个值:
    if name == "Kevin" or name == "Jon" or name == "Inbar":

  2. 编写一系列有效值,并使用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


查看完整回答
反对 回复 2019-05-23
?
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')

为安全起见,我还建议您不要硬编码密码。


查看完整回答
反对 回复 2019-05-23

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信