我正在编写一个安全系统,拒绝未经授权的用户访问。
import sys
print("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.
为什么会出现这种情况?我已经明确声明,只有当name
等于Kevin、Jon或inbar时才授予访问权限。我也尝试过相反的逻辑,如果“kevin”或“jon”或“inbar”==name
,但结果是一样的。
在许多情况下,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
块。
有两种常见的方法可以正确构造这个条件。
>
使用多个
==
运算符对每个值进行显式检查:如果name==“kevin”或name==“jon”或name==“inbar”:
组成一个有效值序列,并使用
in
运算符测试成员资格: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("if a == b or c or d or e: ...")
<_ast.Module object at 0x1031ae6a0>
>>> ast.dump(_)
"Module(body=[If(test=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())]), body=[Expr(value=Ellipsis())], orelse=[])])"
>>>
因此
if
语句的test
如下所示:
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
我正在编写一个安全系统,拒绝未经授权的用户访问。 它按预期授予授权用户访问权限,但也允许未经授权的用户进入! 为什么会发生这种情况?我已经明确声明,只有当等于Kevin、Jon或Inbar时,才允许访问。我也尝试过相反的逻辑,,但结果是一样的。 注意:这个问题旨在作为这个非常常见的问题的规范重复目标。还有另一个热门问题如何针对单个值测试多个变量?这有同样的基本问题,但比较目标是相反的。这个问题不应
问题内容: 我尝试了一些代码,使用XOR在Java中交换两个整数而不使用第三个变量。 这是我尝试的两个交换函数: 这段代码产生的输出是这样的: 我很好奇,为什么这样说: 与这个不同吗? 问题答案: 问题是评估的顺序: 参见JLS第15.26.2节 首先,对左操作数求值以产生一个变量。 如果该评估突然完成,则赋值表达式由于相同的原因而突然完成;右边的操作数不会被评估,并且不会发生赋值。 否则,将保存
问题内容: 我有一个可以接收零或三个命令行参数的python脚本。(要么以默认行为运行,要么需要指定所有三个值。) 诸如此类的理想语法是什么? ? 问题答案: 如果您要使用的是最小形式,请执行以下操作: 这将翻译您的问题的标题。 更新:正如Volatility and Supr正确地说的那样,您可以应用De Morgan的定律并获得等效的: 我的建议是使用对您和其他程序员更重要的形式。第一个意思是
然而,今天我在处理一些代码时,意外地发现以下两个交换给出了不同的结果: 这让我难以置信。有人能给我解释一下这里发生了什么吗?
我尝试了一些代码在Java中交换两个整数,而不使用第三个变量,即使用XOR。 以下是我尝试的两个交换函数: 该代码产生的输出如下: 我很想知道,为什么会有这样的说法: 和这个不一样?