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