写入 locals() 的工作方式与说明它不是的文档相反
Writing to locals() works in contrast to documentation saying its not
我目前正在研究变量范围以及如何修改/复制它们,因为我想在 IPython 中动态地后处理一些结果。
关于 locals()、vars() 和 globals() 的困惑现在对我来说是真实存在的。
特别是因为这段代码的输出:
Python 3.6.1 (v3.6.1:69c0db5050, Mar 21 2017, 01:21:04)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> locals()["test"] = 5
>>> print(test)
5
根据不仅仅是简短的文档,这在我看来是不可能的:
Note, the locals dictionary is only useful for reads since updates to
the locals dictionary are ignored.
(出于 vars() 函数的 description 中所述的任何原因)
希望有人能赐教:)
你在哪里阅读这篇文章?两者 Py 2 docs and Py 3 docs 都有以下免责声明:
Note: The contents of this dictionary should not be modified; changes may not affect the values of local and free variables used by the interpreter.
这准确地说明了这是什么:实现细节。当然,它适用于 CPython,但它可能不适用于其他各种解释器,如 IronPython 和 Jython。这就是所谓的 hack。
不要依赖它来更新任何变量。甚至不要尝试做任何严重的事情,因为它会导致未定义的行为。
在 CPython 3.6.0 中,help(locals)
有以下注释:
NOTE: Whether or not updates to this dictionary will affect name lookups in
the local scope and vice-versa is *implementation dependent* and not
covered by any backwards compatibility guarantees.
然而,CPython 2.7.13 没有这样的注释。
在模块范围内,locals()
returns 可以修改的全局模块字典。函数中的局部变量是不同的。这里,变量没有改变。正如其他地方提到的,这完全取决于实现。你不能指望 locals()
作为一名作家。
>>> def foo():
... x = 2
... locals()['x'] = 3
... print(x)
...
>>>
>>> foo()
2
编辑
在cpython
中,局部变量变成了框架对象上的槽。当 python 运行程序时,"x" 不再是 "x",它是槽中的索引。
>>> from dis import dis
>>> dis(foo)
2 0 LOAD_CONST 1 (2)
2 STORE_FAST 0 (x)
3 4 LOAD_CONST 2 (3)
6 LOAD_GLOBAL 0 (locals)
8 CALL_FUNCTION 0
10 LOAD_CONST 3 ('x')
12 STORE_SUBSCR
4 14 LOAD_GLOBAL 1 (print)
16 LOAD_FAST 0 (x)
18 CALL_FUNCTION 1
20 POP_TOP
22 LOAD_CONST 0 (None)
24 RETURN_VALUE
STORE_FAST 0
表示将当前值(刚好是2)存入slot 0.
我目前正在研究变量范围以及如何修改/复制它们,因为我想在 IPython 中动态地后处理一些结果。 关于 locals()、vars() 和 globals() 的困惑现在对我来说是真实存在的。 特别是因为这段代码的输出:
Python 3.6.1 (v3.6.1:69c0db5050, Mar 21 2017, 01:21:04)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> locals()["test"] = 5
>>> print(test)
5
根据不仅仅是简短的文档,这在我看来是不可能的:
Note, the locals dictionary is only useful for reads since updates to the locals dictionary are ignored.
(出于 vars() 函数的 description 中所述的任何原因)
希望有人能赐教:)
你在哪里阅读这篇文章?两者 Py 2 docs and Py 3 docs 都有以下免责声明:
Note: The contents of this dictionary should not be modified; changes may not affect the values of local and free variables used by the interpreter.
这准确地说明了这是什么:实现细节。当然,它适用于 CPython,但它可能不适用于其他各种解释器,如 IronPython 和 Jython。这就是所谓的 hack。
不要依赖它来更新任何变量。甚至不要尝试做任何严重的事情,因为它会导致未定义的行为。
在 CPython 3.6.0 中,help(locals)
有以下注释:
NOTE: Whether or not updates to this dictionary will affect name lookups in
the local scope and vice-versa is *implementation dependent* and not
covered by any backwards compatibility guarantees.
然而,CPython 2.7.13 没有这样的注释。
在模块范围内,locals()
returns 可以修改的全局模块字典。函数中的局部变量是不同的。这里,变量没有改变。正如其他地方提到的,这完全取决于实现。你不能指望 locals()
作为一名作家。
>>> def foo():
... x = 2
... locals()['x'] = 3
... print(x)
...
>>>
>>> foo()
2
编辑
在cpython
中,局部变量变成了框架对象上的槽。当 python 运行程序时,"x" 不再是 "x",它是槽中的索引。
>>> from dis import dis
>>> dis(foo)
2 0 LOAD_CONST 1 (2)
2 STORE_FAST 0 (x)
3 4 LOAD_CONST 2 (3)
6 LOAD_GLOBAL 0 (locals)
8 CALL_FUNCTION 0
10 LOAD_CONST 3 ('x')
12 STORE_SUBSCR
4 14 LOAD_GLOBAL 1 (print)
16 LOAD_FAST 0 (x)
18 CALL_FUNCTION 1
20 POP_TOP
22 LOAD_CONST 0 (None)
24 RETURN_VALUE
STORE_FAST 0
表示将当前值(刚好是2)存入slot 0.