globals()vs locals()可变性 [英] globals() vs locals() mutability

查看:153
本文介绍了globals()vs locals()可变性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Python中,globals()返回全局符号表的表示形式,而locals()返回本地状态的表示形式.两者都返回字典时,对globals()的更改将在全局符号表中生效,而对locals()的更改则无效.

In Python, globals() returns a representation of the global symbol table, while locals() returns a representation of the local state. While both return a dictionary, changes to globals() are effected in the global symbol table, while change to locals() have no effect.

为什么会这样?

推荐答案

函数局部语言在编译时进行了高度优化和确定,CPython建立在无法在运行时动态更改已知局部语言的基础上.

Function locals are highly optimised and determined at compile time, CPython builds on not being able to alter the known locals dynamically at runtime.

解码功能字节码时可以看到以下内容:

You can see this when decoding a function bytecode:

>>> 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        

LOAD_FAST

The LOAD_FAST and STORE_FAST opcodes use indices to load and store variables, because on a frame the locals is implemented as an array. Access to an array is faster than using a hash table (dictionary), such as used for the global namespace.

locals()函数在函数中使用时,然后返回此数组的 reflection 作为字典.更改locals()字典不会将其反映回数组中.

The locals() function, when used in a function, then returns a reflection of this array as a dictionary. Altering the locals() dictionary won't then reflect that back into the array.

在Python 2中,如果在代码中使用exec语句,则优化会(部分)中断;在这种情况下,Python使用速度较慢的 LOAD_NAME操作码:

In Python 2, if you use the exec statement in your code then the optimisation is (partly) broken; Python uses the slower LOAD_NAME opcode in that case:

>>> def bar(code):
...     exec code
...     return a + 'baz'
... 
>>> dis.dis(bar)
  2           0 LOAD_FAST                0 (code)
              3 LOAD_CONST               0 (None)
              6 DUP_TOP             
              7 EXEC_STMT           

  3           8 LOAD_NAME                0 (a)
             11 LOAD_CONST               1 ('baz')
             14 BINARY_ADD          
             15 RETURN_VALUE        

另请参阅此针对Python 3的错误报告,其中exec()(Py3中的函数)不适用"不再允许您设置本地名称:

Also see this bug report against Python 3 where exec() (a function in Py3) doesn't allow you to set local names anymore:

动态修改函数的本地不是 可能没有几个后果:通常,功能本地变量不是 存储在字典中,但存储在一个数组中,其索引在 从已知语言环境编译时间.这至少与新 由exec添加的本地人. 旧版exec语句规避了这一问题,因为 编译器知道如果发生了没有全局/局部参数的exec 在函数中,该名称空间将是未优化的",即不使用 locals数组.由于exec()现在是常规函数,因此编译器会执行 不知道什么是"exec"可能会绑定,因此无法治疗的是

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.

这篇关于globals()vs locals()可变性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆