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

时间:2014-09-20 23:40:52

标签: python dynamic runtime global-variables

如果我这样做:

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

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

globals()['y']=3

似乎y也是在运行时创建的。为什么会这样?动态行为来自哪里?

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

1 个答案:

答案 0 :(得分:1)

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

如果你问为什么Python没有将它优化为静态分配......好吧,想想它必须做什么。

首先,检测'y'是一个文字很容易;这些信息就在AST中。

但是检测到dict是你模块的全球词典要困难得多。 globals不是关键字或其他任何神奇的关键字,它只是builtins中的常规功能。您可以使用全局,非本地或本地名称或monkeypatch builtins隐藏它,甚至可以替换全局变量的内置函数,因此无法访问它。因此,它必须进行充分的分析,以确定globals上的名称查找除了适当的全局字典之外不可能返回任何内容。

并且,不仅如此,为了使其有用,语言必须要求每个实现进行相同的优化。否则,您可以根据优化是否发生,从某些程序中获得不同的语义。

同样值得记住的是,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