Python2与Python3的语法区别引起了我对exec的注意,进而探讨一下python的命名空间(作用域)
exec()函数
exec()最有用的地方在于可以动态地创建代码字符串。然而,如果字符串是从其他地方获得的——很有可能是用户——那么几乎不能确定其中到底包含什么代码。所以为了安全起见,可以增加一个字典,起到命名空间的作用。
例:
# Python2版:
from math import sqrt
scope = {
}
exec 'sqrt = 1' in scope
print(sqrt(4))
print(scope['sqrt'])
#Python3版:
from math import sqrt
scope = {
}
exec('sqrt = 1', scope)
print(sqrt(4))
print(scope['sqrt'])
#输出为
2.0
1
可以看到,潜在的破坏性代码并不会覆盖sqrt函数,原来的函数能正常工作,而通过exec赋值的变量sqrt只在它的作用域内有效。
这时如果将scope打印出来的话,会看到其中包含很多东西,
因为內建的_builtins_字典自动包含所有的內建函数和值。
{'__builtins__':
{'__name__': 'builtins',
'__doc__': "Built-in functions, exceptions, and other objects.\n\nNoteworthy: None is the `nil' object; Ellipsis represents `...' in slices.",
'__package__': '',
'__loader__': <class '_frozen_importlib.BuiltinImporter'>,
'__spec__': ModuleSpec(name='builtins', loader=<class '_frozen_importlib.BuiltinImporter'>),
'__build_class__': <bui