globals()与locals()可变

2024-06-07 00:30:18 发布

您现在位置:Python中文网/ 问答频道 /正文

在Python中,globals()返回全局符号表的表示,而locals()返回局部状态的表示。当两者都返回一个字典时,对globals()的更改在全局符号表中生效,而对locals()的更改没有影响。在

为什么会这样?在


Tags: 字典状态局部全局符号表globalslocals生效
1条回答
网友
1楼 · 发布于 2024-06-07 00:30:18

函数局部变量在编译时被高度优化和确定,CPython的基础是不能在运行时动态地改变已知的局部变量。在

解码字节码时可以看到:

>>> import dis
>>> def foo():
...     a = 'bar'
...     return a + 'baz'
... 
>>> dis.dis(foo)
  2           0 LOAD_CONST               1 ('bar')
              3 STORE_FAST               0 (a)

  3           6 LOAD_FAST                0 (a)
              9 LOAD_CONST               2 ('baz')
             12 BINARY_ADD          
             13 RETURN_VALUE        

^{}^{}操作码使用索引来加载和存储变量,因为在帧上,局部变量被实现为数组。访问数组比使用哈希表(字典)更快,例如用于全局命名空间。在

当在函数中使用locals()函数时,将返回该数组的一个反射作为字典。更改locals()字典不会将其反映回数组中。在

在Python2中,如果您在代码中使用exec语句,那么优化(部分)中断;在这种情况下,Python使用较慢的^{} opcode

^{pr2}$

另请参见bug report against Python 3,其中exec()(Py3中的函数)不再允许您设置本地名称:

To modify the locals of a function on the fly is not possible without several consequences: normally, function locals are not stored in a dictionary, but an array, whose indices are determined at compile time from the known locales. This collides at least with new locals added by exec. The old exec statement circumvented this, because the compiler knew that if an exec without globals/locals args occurred in a function, that namespace would be "unoptimized", i.e. not using the locals array. Since exec() is now a normal function, the compiler does not know what "exec" may be bound to, and therefore can not treat is specially.

相关问题 更多 >