如何让字典中字符串形式的三元表达式经eval()执行不报错?
问题根源与解决方案
首先得说清楚:你之前觉得“直接运行三元表达式正常”,大概率是只测试了条件满足的情况——一旦条件不满足,哪怕直接运行原来的代码也会报错!
问题出在你把赋值语句硬塞进了三元表达式里:Python的三元运算符a if b else c是表达式(用来计算一个值),而y += 1是赋值语句。你的代码会被Python解析成:
y += (1 if y == 1 else print('F'))
当条件不满足时,print('F')会执行,但它返回None,接下来就会尝试y += None,这必然触发TypeError(整数和None类型不能相加)。
正确的处理方式
既然你的需求是分支执行语句(满足条件就做赋值,否则打印提示),就不该用三元表达式,直接把字典里的字符串改成标准的if-else语句块即可:
# 先定义初始变量 x = 1 y = 1 c = { 1: "if y == 1: y += 1 else: print('F')", 2: "if y == 2: y -= 1 else: print('F')", 3: "if x == 1: x += 1 else: print('F')", 4: "if x == 2: x -= 1 else: print('F')" } for i in range(1, 5): eval(c[i])
为什么这样能行?
eval()不仅可以执行表达式,也能执行单条语句或语句块(只要语法正确)。改成if-else语句后,逻辑就变成了:条件满足时执行赋值,不满足时执行打印,完全符合你的需求,不会再出现类型错误。
额外优化建议
如果是在生产环境中使用eval(),一定要注意安全风险——如果字典里的字符串来自不可信来源,很容易被注入恶意代码。如果可以的话,建议用函数代替字符串,比如:
x = 1 y = 1 def func1(): global y if y == 1: y += 1 else: print('F') def func2(): global y if y == 2: y -= 1 else: print('F') def func3(): global x if x == 1: x += 1 else: print('F') def func4(): global x if x == 2: x -= 1 else: print('F') c = {1: func1, 2: func2, 3: func3, 4: func4} for i in range(1, 5): c[i]()
这种方式比用eval()更安全,也更易维护。
内容的提问来源于stack exchange,提问作者Andrew
相关产品推荐
相关产品推荐

