在模块级别声明的函数永远不会有闭包,并通过LOAD_GLOBAL
访问非局部变量。
在模块级别声明不的函数可能有一个闭包,如果这些变量不是全局变量,则可以通过LOAD_DEREF
访问非局部变量。
基本上我们有三种方式来存储和加载变量GLOBAL
(全局),FAST
(本地)和DEREF
(非本地,封闭,覆盖)。
为什么GLOBAL
?如果你让所有函数都有它们的闭包,FAST
和DEREF
就不够了吗?非局部变量和全局变量之间是否存在一些重要区别?这可能是由于性能问题,因为全局变量(如模块级别定义的所有函数和类(包括它们的方法)加上内部函数)通常比非局部变量更常见吗?
答案 0 :(得分:5)
编译期间枚举本地名称和封闭名称。在运行时,它们存储在C数组中并使用整数/索引进行访问。 LOAD_FAST
和LOAD_DEREF
采用C整数并执行C数组查找。
全局名称无法在编译时枚举,它们可以在运行时由整个过程中的任何代码添加和删除。这与对象属性类似 - 因为全局变量 是模块对象的属性。因此,它们存储在字典中,并且实现访问它们与本地和封闭名称完全不同。 LOAD_GLOBAL
接受一个字符串(常量)并执行字典查找。