问题描述
我正在测试某个函数上的预定义 dict 属性,但结果却出乎意料。考虑以下代码:
>>> def func():
x = 7
a = 0
print(func.__dict__)
>>> func()
{}
毕竟,我确实在函数的名称空间中定义了两个变量。那么为什么这些名称不出现在函数的 dict 属性中?
解决方法
函数的__dict__
保存属性,而不保存局部变量。局部变量特定于函数的每次执行,而不是函数本身,因此您无法通过检查函数来获取局部变量值。
如果您分配了属性:
func.blah = 3
将显示在__dict__
中。
(__dict__
并不拥有所有属性-还有其他创建属性的方法,例如,这就是__dict__
本身不出现在__dict__
中的原因。 )
功能对象的__dict__
属性存储为分配给功能对象的属性。
>>> def foo():
... a = 2
... return a
...
>>> foo.bar = 12
>>> foo.__dict__
{'bar': 12}
函数 object 的属性与函数 call 中存在的局部变量无关。前者是唯一的(每个函数对象有一个__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__
在那里支持函数属性,它不是函数主体作用域的名称空间或符号表 。您可以阅读PEP-232以获得有关函数属性的更多信息。