locals 字典是什么时候设置的?

When is the locals dictionary set?

一个模块拥有一个字典来跟踪它的上下文,例如在执行的某个点定义的名称。可以通过模块本身的 vars(module) (or module.__dict__) if module was imported, or by a call to the locals 内置函数访问此词典:

Update and return a dictionary representing the current local symbol table.

但是当我尝试从一个函数访问本地字典时,我发现自己有点困惑。仅包含以下内容的脚本的输出是一个空字典:

def list_locals():
    print(locals())

list_locals()

但另一方面,如果脚本仅包含以下内容,则输出是预期的字典,包含 __name____doc__ 和其他模块级变量:

print(locals())

那么,本地人词典的内容是什么时候设置的呢? 另外,locals函数定义中的"update"是什么意思?

模块的命名空间是全局命名空间,通过globals()访问。没有单独的局部名称空间,因此 locals(),在函数之外,只有 return 全局名称空间。

只有函数才有本地命名空间。请注意 locals() 是该命名空间的一种单向反映;函数的 CPython 实现是高度优化的,您不能通过 locals() 字典添加或更改局部变量。每当命名空间在对该函数的调用之间发生变化时,由 locals() 编辑的词典 return 就会更新。

另请注意,列表/字典/集合理解、生成器表达式和 class 主体等内容实际上也作为函数执行,尽管具有不同的命名空间规则。在这种情况下 locals() 也将 return 单独的函数本地命名空间。

如果您在同一个函数调用期间多次调用 locals(),它将 return 同一个字典。

>>> def f():
...     d = locals()
...     assert 'd' not in d
...     locals()
...     assert 'd' in d
...     assert d is locals()
...     print(d)
... 
>>> f()
{'d': {...}}

"Update" 在这种情况下意味着更新该字典的内容以反映存在的局部变量的当前范围,但如果您保留对该字典的引用,则该字典仍将被使用。

另请注意,locals 字典不包含 'f' 的键,即使您可以在函数执行过程中访问它。如果不是很明显,那是全局的,不是局部的。