在模块级别声明的函数永远不会有闭包,并通过LOAD_GLOBAL
访问非局部变量。全局变量与解除引用变量的实现
声明的功能而不是在模块级别可能有闭包并通过LOAD_DEREF
访问非本地变量,如果这些变量不是全局变量的话。所以基本上我们有三种存储和加载变量的方法:GLOBAL
(全局),FAST
(本地)和DEREF
(非本地,封闭,覆盖)。
为什么GLOBAL
?如果让所有函数都关闭,那么FAST
和DEREF
就足够了吗?非局部变量和全局变量之间是否存在一些重要区别?这可能是由于性能问题,因为也许全局变量(如模块级定义的所有函数和类(包括它们的方法)加上内建函数)通常比非局部变量更常见?
然后我猜在编译期间的枚举过程中,编译器还会判断一个变量是否(可能)从一个封闭范围内访问,并且在这些情况下使用'STORE_DEREF'而不是'STORE_FAST'。这是正确的吗? – Hyperboreus
@Hyperboreus是的,它只是搜索作业和非本地声明。 – delnan
这是否也意味着我需要两次扫描来编译一个块(范围,帧,我不知道正确的术语)?我的意思是,我需要所有*封闭*块的信息以便在“STORE_FAST”和“STORE_DEREF”之间做出决定。同时,我需要关于所有*封闭*块的信息,以便在“LOAD_DEREF”和“LOAD_GLOBAL”之间做出决定。因此编译一个孩子取决于父母,反之亦然。还是我得到这个错误? – Hyperboreus