我正在编写一个安全系统,拒绝未经授权的用户访问。
name = input("Hello. Please enter your name: ")
if name == "Kevin" or "Jon" or "Inbar":
print("Access granted.")
else:
print("Access denied.")
它按预期授予授权用户访问权限,但也允许未经授权的用户进入!
Hello. Please enter your name: Bob
Access granted.
为什么会发生这种情况?我已经明确声明,只有当name
等于Kevin、Jon或Inbar时,才允许访问。我也尝试过相反的逻辑,如果“Kevin”或“Jon”或“Inbar”==name
,但结果是一样的。
注意:这个问题旨在作为这个非常常见的问题的规范重复目标。还有另一个热门问题如何针对单个值测试多个变量?这有同样的基本问题,但比较目标是相反的。这个问题不应该作为那个问题的重复被关闭,因为这个问题是Python的新手遇到的,他们可能很难将反向问题中的知识应用到他们的问题中。
简单的工程问题,让我们更进一步。
In [1]: a,b,c,d=1,2,3,4
In [2]: a==b
Out[2]: False
但是,继承自C语言的Python将非零整数的逻辑值计算为True。
In [11]: if 3:
...: print ("yey")
...:
yey
现在,Python构建在该逻辑的基础上,并允许您使用逻辑文本,例如或整数,等等
In [9]: False or 3
Out[9]: 3
终于
In [4]: a==b or c or d
Out[4]: 3
正确的书写方式是:
In [13]: if a in (b,c,d):
...: print('Access granted')
为了安全起见,我还建议你不要硬编码密码。
如果name==“Kevin”或“Jon”或“Inbar”,则在中有3个条件检查:
name=="Kevin"
- 乔恩
- Inbar
这个if语句等价于
if name == "Kevin":
print("Access granted.")
elif "Jon":
print("Access granted.")
elif "Inbar":
print("Access granted.")
else:
print("Access denied.")
由于
elif"Jon"
将始终为真,因此授予任何用户访问权限
您可以使用下面的任何一种方法
快啊
if name in ["Kevin", "Jon", "Inbar"]:
print("Access granted.")
else:
print("Access denied.")
缓慢的
if name == "Kevin" or name == "Jon" or name == "Inbar":
print("Access granted.")
else:
print("Access denied.")
慢不必要的代码
if name == "Kevin":
print("Access granted.")
elif name == "Jon":
print("Access granted.")
elif name == "Inbar":
print("Access granted.")
else:
print("Access denied.")
在许多情况下,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"):
或
运算符选择具有正真值的第一个参数:
if "Jon":
由于Jon具有正真值,if
块将执行。这就是为什么“授权访问”会被打印出来,而不管给出的名字是什么。
如果“Kevin”或“Jon”或“Inbar”==name,所有这些推理也适用于表达式。第一个值,
“Kevin”
,为true,因此执行if
块。
有两种常见的方法可以正确构造此条件。
>
使用多个
==
运算符显式检查每个值:
if name == "Kevin" or name == "Jon" or name == "Inbar":
组成一个有效值的集合(例如集合、列表或元组),并使用
运算符中的测试成员资格:
if name in {"Kevin", "Jon", "Inbar"}:
一般而言,应优先选择第二种,因为它更容易阅读,也更快:
>>> import timeit
>>> timeit.timeit('name == "Kevin" or name == "Jon" or name == "Inbar"',
setup="name='Inbar'")
0.4247764749999945
>>> timeit.timeit('name in {"Kevin", "Jon", "Inbar"}', setup="name='Inbar'")
0.18493307199999265
对于那些可能想要证明
if a==b或c或d或e的人:...
确实是这样解析的。内置的ast
模块提供了一个答案:
>>> import ast
>>> ast.parse("a == b or c or d or e", "<string>", "eval")
<ast.Expression object at 0x7f929c898220>
>>> print(ast.dump(_, indent=4))
Expression(
body=BoolOp(
op=Or(),
values=[
Compare(
left=Name(id='a', ctx=Load()),
ops=[
Eq()],
comparators=[
Name(id='b', ctx=Load())]),
Name(id='c', ctx=Load()),
Name(id='d', ctx=Load()),
Name(id='e', ctx=Load())]))
可以看到,它是应用于四个子表达式的布尔运算符:比较
a==b
;和简单表达式c
,d
和e
。
问题内容: 我正在编写一个拒绝访问未授权用户的安全系统。 它可以按预期授予授权用户访问权限,但也允许未经授权的用户使用! 为什么会发生这种情况?我已经明确指出仅在name等于,或 时才授予访问权限。我也尝试过相反的逻辑if ,但是结果是一样的。 问题答案: 在许多情况下,Python的外观和行为都像自然的英语,但这是这种抽象失败的一种情况。人们可以使用上下文线索来确定和是与动词连接的对象,但是Py
问题内容: 例如: 当不带参数调用时,上述函数将打印并返回 Python为什么要这样做?如何最好地利用这一功能? 问题答案: “ ”表达式对赋值的作用: 我们有时会在Python中看到这样的示例,以三元赋值代替条件表达式(实际上,这有助于启发该语言添加条件语句)。 如果返回,则分配值为 条件表达式的相同用例(即三元分配) 这是一个条件表达式的示例,该条件表达式可以完成相同的任务,但可能不那么神秘。
我有以下功能: 此代码给出了
这部分是学术性的,就我的目的而言,我只需要四舍五入到小数点后两位;但我很想知道发生了什么会产生两种略有不同的结果。 这是我编写的测试,将其缩小到最简单的实现: 但它失败了,输出如下: 有谁能详细解释一下是什么原因导致 我在一个答案中寻找的一些要点是:精度损失在哪里?哪种方法是首选的,为什么?哪一个实际上是正确的?(在纯数学中,不可能两者都是对的。也许两者都是错的?)对于这些算术运算,有没有更好的解
我正在编写一个安全系统,拒绝未经授权的用户访问。 它按预期授予授权用户访问权限,但也允许未经授权的用户进入! 为什么会出现这种情况?我已经明确声明,只有当等于Kevin、Jon或inbar时才授予访问权限。我也尝试过相反的逻辑,,但结果是一样的。
问题内容: 考虑以下示例: 我不确定Java语言规范中是否有一项规定要加载变量的先前值以便与右侧()进行比较,该变量应按照方括号内的顺序进行计算。 为什么第一个表达式求值,而第二个表达式求值?我本来希望先被评估,然后再与自身()比较并返回。 这个问题与Java表达式中子表达式的求值顺序不同,因为这里绝对不是“子表达式”。需要 加载 它以进行比较,而不是对其进行“评估”。这个问题是特定于Java的,