为什么这个函数的__dict__属性是一个空字典?

Why is the __dict__ attribute of this function an empty dictionary?

我正在测试一个函数的预定义 dict 属性,我得到了一个我没想到的结果。考虑以下代码:

>>> def func():
       x = 7
       a = 0
       print(func.__dict__)

    
>>> func()
{}

毕竟我确实在函数的命名空间里定义了两个变量。那么为什么这些名称没有出现在函数的 dict 属性中呢?

函数的 __dict__ 包含 属性 ,而不是局部变量。局部变量特定于函数的每次执行,而不是函数本身,因此您无法通过检查函数来获取局部变量值。

如果您分配了属性:

func.blah = 3

将显示在 __dict__ 中。

(A __dict__ 不包含所有属性 - 还有其他方法可以创建属性,这就是为什么 __dict__ 本身不会出现在 __dict__ 中的原因,因为例如。)

函数对象的 __dict__ 属性存储分配给 函数对象的属性

>>> def foo():
...     a = 2
...     return a
...
>>> foo.bar = 12
>>> foo.__dict__
{'bar': 12}

函数对象的属性与函数调用期间存在的局部变量无关。前者是唯一的(每个函数对象有一个 __dict__)后者不是(一个函数可以使用单独的局部变量多次调用)。

>>> def nfoo(n: int):
...     print(f'level {n} before:', locals())
...     if n > 0:
...        nfoo(n - 1)
...     print(f'level {n} after: ', locals())
...
>>> nfoo(2)
level 2 before: {'n': 2}
level 1 before: {'n': 1}
level 0 before: {'n': 0}
level 0 after:  {'n': 0}
level 1 after:  {'n': 1}
level 2 after:  {'n': 2}

请注意每个级别的 locals 如何同时存在,但为相同的名称保留不同的值。

__dict__ 是为了支持函数属性,它不是命名空间也不是符号 table 用于函数体范围 。您可以阅读 PEP-232 以获取有关函数属性的更多信息。