动态创建变量和修改全局()



如果我这样做:

newvar = raw_input()
globals()[newvar] = 4

很明显,生成的变量是在运行时创建的,因为这是唯一的可能性。然而,如果我这样做:

globals()['y']=3

似乎y也是在运行时创建的。为什么会这样?动态行为从何而来?

附言:我知道这是一种不好的做法,我只是想了解一下。

您的模块(或exec上下文等)的全局是dict,而globals()只返回该dict。之后,['y'] = 3部分就像任何其他字典分配一样。

如果你问Python为什么不将其优化为静态分配……那么,想想它必须做什么。

首先,检测'y'是一个文字非常容易;该信息就在AST中。

但是检测dict是模块的全局字典要困难得多。globals不是一个关键字或任何其他神奇的东西,它只是builtins中的一个常规函数。您可以用全局、非本地或本地名称或monkeypatch builtins隐藏它,甚至可以替换全局的内置名称,使其不可访问。因此,它必须进行充分的分析,以确定在globals上的名称查找不可能返回任何内容,而只能返回适当的全局dict

不仅如此,为了使这一点变得有用,该语言必须要求每个实现都进行相同的优化。否则,根据是否进行了优化,您可以从一些程序中获得不同的语义。

同样值得记住的是,CPython除了基本的窥视孔优化之外没有做任何事情,因此您必须从头开始为更复杂的优化器构建基础设施,只需添加一个小的更改。

除此之外,对同一全局字典的引用存储在各处。因此,即使进行了这种优化,您仍然可以同样轻松地欺骗Python:

g = globals()
g['y'] = 3
globals().__getitem__('globals')()['y'] = 3
def f(): pass
f.__globals__['y'] = 3
inspect.currentframe().f_globals['y'] = 3

相关内容

  • 没有找到相关文章

最新更新