python - 如何/是否可以关闭短路评估?
问题描述
我正在编写一种命令行用户界面,其中可以给出任意布尔表达式作为输入。必须在某个更新后更改的字典上重复评估此表达式。
这是简化的代码:
import traceback
def update_my_dict():
return {'a': 1}
my_dict = {'a': 0}
bool_exp = input()
# -- verify code can be executed in the current context
try:
result = eval(bool_exp, my_dict)
except Exception:
print(f'Expression cannot be evaluated, evaluation raise the following error:')
print(traceback.format_exc())
quit()
# -- verify code return a boolean
if not isinstance(result, bool):
print(f'Expression return {type(result)}, expect bool')
quit()
# -- go
while not eval(bool_exp, my_dict):
my_dict = update_my_dict()
在运行最后一个 while 循环之前,我想验证表达式是否可以在当前上下文中执行并确保它返回一个布尔值。
我的问题是,如果表达式是,例如,表达式bool_exp = a == 1 and b == 2
的第一次测试评估同时返回 false 但不引发异常,因为关闭了惰性评估。但是当my_dict
更新时会引发错误。
那么,是否有可能以某种方式禁用第一次测试评估的惰性/短路评估?我使用ast搜索了一些解决方案,但它似乎很复杂,因为它bool_exp
可以是任意长且复杂的,例如包含纠缠的布尔表达式等。
PS:我知道eval()
在一般情况下是不安全的,但我的代码将无法在外部使用
PS2:我知道它可以在 while 循环中捕获异常,但它看起来有点优化,知道my_dict
键在更新时永远不会改变,只会改变它们的值。此外,这个问题更像是是否可以控制评估行为
编辑
“但你可以使用&
and|
代替and
and or
!” 不,我不知道将输入什么作为输入。所以用户可以输入任何她想要的。
A 正确的输入表达式:
- 应该返回一个布尔值。
- 应该只在测试中涉及字典键。
“正确”意味着它将在结束的 while 循环中重复评估,而不会引发任何异常。我们假设字典中的键将保持不变。即只有字典的值会在更新阶段发生变化。换句话说,第一个try/except
目的是验证表达式是否只对 中的变量进行一些测试my_dict
。
我无法进一步解释这个在全球范围内的使用,否则我需要一个很长的帖子,丢失似乎不相关的信息来解决这个问题。
解决方案
您可以将“验证”代码放入循环中。这是有道理的,因为您的输入正在发生变化,因此您应该在每次更改时对其进行验证。eval
每次 dict 值更改时,您已经对表达式进行了评估,因此与当前代码相比,唯一添加的逻辑isinstance
是现在对 dict 的每次更改都进行了检查:
import traceback
def update_my_dict():
return {'a': 1}
my_dict = {'a': 0}
bool_exp = input()
# -- go
while True:
# -- verify code can be executed in the current context
try:
result = eval(bool_exp, my_dict)
except Exception:
print(f'Expression cannot be evaluated, evaluation raise the following error:')
print(traceback.format_exc())
quit()
# -- verify code return a boolean
if not isinstance(result, bool):
print(f'Expression return {type(result)}, expect bool')
quit()
if result:
break
my_dict = update_my_dict()
在相同的示例输入中a == 1 and b == 2
,这将输出:
Expression cannot be evaluated, evaluation raise the following error:
Traceback (most recent call last):
File "main.py", line 14, in <module>
result = eval(bool_exp, my_dict)
File "<string>", line 1, in <module>
NameError: name 'b' is not defined
推荐阅读
- c# - 如何在 Visual Studio 中以编程方式在调试和发布之间进行更改
- python - 通过从我的熊猫数据框中排除某些代码来过滤数据
- snowflake-cloud-data-platform - 如何在 Snowflake 中查询多个 JSON 文档模式?
- macos - Mac钩子函数
- regex - 正则表达式:可以在正则表达式中进行子匹配吗?
- c# - 角色在第一次跳跃时跳得非常高,然后正常跳跃。我该如何解决?(统一二维)
- angular - 如何在 Angular 的问题路由之间添加动画?
- mysql - 下面使用的 CROSS JOIN 模型是否有更快的替代方案?
- forms - Flutter - 首次使用表单后不显示键盘
- javascript - 如何在循环中跳过未定义的值?