这里有很多好的答案,但没有一个描述 eval() 在其 globals 和 locals kwargs的上下文中的使用,即 eval(expression, globals=None, locals=None) (参见 eval here的文档) .
这些可用于限制通过 eval 方法可用的方法 . 例如,如果你加载一个新的python解释器, locals() 和_686919将是相同的,看起来像这样:
>>> globals()
{'__loader__': , '__doc__': None,
'__spec__': None, '__builtins__': ,
'__package__': None, '__name__': '__main__'}
builtins 模块中肯定有一些方法可以对系统造成重大损害 . 但是有可能阻止任何事情和我们所做的一切事情 . 假设我们要构建一个列表来表示系统上可用核心的域 . 对我来说,我有8个核心所以我想要一个列表 [1, 8] .
>>>from os import cpu_count()
>>>eval('[1, cpu_count()]')
[1, 8]
同样 __builtins__ 全部可用 .
>>>eval('abs(-1)')
1
好 . 因此,我们看到一个我们想要暴露的方法,以及一个我们不希望暴露的方法(很多可能更复杂的方法)的例子 . 所以让我们阻止一切 .
>>>eval('[1, cpu_count()]', {'__builtins__':None}, {})
TypeError: 'NoneType' object is not subscriptable
我们已经有效地阻止了所有 __builtins__ 方法,因此为我们的系统带来了一定程度的保护 . 此时,我们可以开始添加我们想要暴露的方法 .
>>>from os import cpu_count
>>>exposed_methods = {'cpu_count': cpu_count}
>>>eval('cpu_count()', {'__builtins__':None}, exposed_methods)
8
>>>eval('abs(cpu_count())', {'__builtins__':None}, exposed_methods)
TypeError: 'NoneType' object is not subscriptable
现在我们有cpu_count方法可用,同时仍然阻止我们不想要的一切 . 在我看来,这是超级强大的,显然从其他答案的范围而不是一个常见的实现 . 对于这样的事情有很多用途,只要处理得当,我个人觉得 eval 可以安全地用于很有 Value .
N.B.
关于这些 kwargs 的其他一些很酷的事情是你可以开始使用速记代码 . 让's say you use eval as part of a pipeline to execute some imported text. The text doesn't需要具有确切的代码,它可以遵循一些模板文件格式,并且仍然执行您想要的任何内容 . 例如:
>>>from os import cpu_count
>>>eval('[1,cores]', {'__builtins__': None}, {'cores': cpu_count()})
[1, 8]