Python 编写to locals()的工作原理与说明其不可用的文档不同

Python 编写to locals()的工作原理与说明其不可用的文档不同,python,scope,namespaces,global,local,Python,Scope,Namespaces,Global,Local,我目前正在修补变量作用域以及如何修改/复制它们,因为我想在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

我目前正在修补变量作用域以及如何修改/复制它们,因为我想在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
根据不只是简单的文件,我认为这是不可能的:

请注意,“局部变量”词典仅适用于自更新到后的读取 本地词典被忽略

(这是由于vars()函数的


我希望有人能启发我:)

你在哪里读这篇文章?和都有以下免责声明:

:本词典内容不得修改;更改可能不会影响解释器使用的本地变量和自由变量的值

这正好说明了这是什么:一个实现细节。当然,它在CPython中工作,但在其他各种解释器中可能不工作,比如IronPython和Jython。这就是所谓的黑客

不要依赖它来更新任何变量。甚至不要尝试做任何严重的事情,因为它会导致未定义的行为

在CPython 3.6.0中,
help(locals)
有以下注释:

注意:此词典的更新是否会影响中的名称查找
本地范围,反之亦然*依赖于实现*而不是
受任何向后兼容性保证的保护。

然而,CPython 2.7.13没有这样的注释。

你在哪里读到这篇文章?和都有以下免责声明:

:本词典内容不得修改;更改可能不会影响解释器使用的本地变量和自由变量的值

这正好说明了这是什么:一个实现细节。当然,它在CPython中工作,但在其他各种解释器中可能不工作,比如IronPython和Jython。这就是所谓的黑客

不要依赖它来更新任何变量。甚至不要尝试做任何严重的事情,因为它会导致未定义的行为

在CPython 3.6.0中,
help(locals)
有以下注释:

注意:此词典的更新是否会影响中的名称查找
本地范围,反之亦然*依赖于实现*而不是
受任何向后兼容性保证的保护。

但是,CPython 2.7.13没有此类注释。

在模块范围内,
locals()
返回可修改的全局模块dict。函数中的局部变量是不同的。在这里,变量没有改变。正如其他地方提到的,这完全取决于实现。你不能依靠
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\u FAST 0
意味着将当前值(正好是2)存储到插槽0中。

在模块范围内,
locals()
返回可修改的全局模块dict。函数中的局部变量是不同的。在这里,变量没有改变。正如其他地方提到的,这完全取决于实现。你不能依靠
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\u FAST 0
意味着将当前值(正好是2)存储到插槽0中。

您是
局部变量
全局变量
,因此可以进行写入。这被视为
vars()是局部变量()是全局变量()
给出了
True
。该注释似乎是一个文档错误。您是
locals
globals
,因此可以进行编写。这被视为
vars()是locals()是globals()
给出了
True
。那张便条看起来像是一个文档错误。首先:非常感谢!我已经添加了文档的链接。我将停止修改locals(),但您知道有什么方法可以将函数的所有局部变量复制到另一个函数,该函数包含在通过IPython动态导入的模块中?我希望避免复制到导入模块中的globals()。你是否知道有什么方法可以让我修改局部变量?@sh4kesbeer不必像那样修改变量,只需将值保存在实际的字典中即可。这样,你就可以还字典了。如果不像这样重新设计它,真的没有办法做到这一点,因为动态变量并不意味着要分配给。好的,谢谢!我希望能够构建某种处理管道,在其中复制本地“工作区”,但这似乎不能转化为python。首先,我会试着习惯字典上的符号:非常感谢!我已经添加了文档的链接。我将停止修改locals(),但您知道有什么方法可以将函数的所有局部变量复制到另一个函数,该函数包含在通过IPython动态导入的模块中?我希望避免复制到导入模块中的globals()。你是否知道有什么方法可以让我修改局部变量?@sh4kesbeer不必像那样修改变量,只需将值保存在实际的字典中即可。这样,你就可以还字典了。如果不像这样重新设计它,真的没有办法做到这一点,因为动态变量并不意味着要分配给。好的,谢谢!我希望能够构建某种处理管道,在其中复制本地“工作区”,但这似乎不能转化为python。我将试着习惯字典中的符号,然后用internetly替换
print(x)