Reputation: 93
I was testing out the pre-defined dict attribute on a function, and I got a result I didn't expect to get. Consider the following code:
>>> def func():
x = 7
a = 0
print(func.__dict__)
>>> func()
{}
After all, I did define two variables in the namespace of the function. So why aren't these names appearing in the dict attribute of the function?
Upvotes: 0
Views: 1151
Reputation: 2372
__dict__
is there to support function attributes, it's not a namespace nor a symbol table for the function body scope. You can read PEP-232 for further information regarding function attributes.
Upvotes: 1
Reputation: 50146
The __dict__
attribute of a function object stores attributes assigned to the function object.
>>> def foo():
... a = 2
... return a
...
>>> foo.bar = 12
>>> foo.__dict__
{'bar': 12}
Attributes of the function object are not related to the local variables that exist during the function call. The former is unique (there is one __dict__
per function object) the latter are not (a function may be called multiple times with separate local variables).
>>> 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}
Note how the locals
of each level exist at the same time but hold separate values for the same name.
Upvotes: 1
Reputation: 281287
A function's __dict__
holds attributes, not local variables. Local variables are specific to each execution of a function, not to the function itself, so you can't get local variable values by inspecting a function.
If you assigned an attribute:
func.blah = 3
that would show up in the __dict__
.
(A __dict__
doesn't hold all attributes - there are other ways to create attributes, which is why __dict__
itself doesn't show up in the __dict__
, for example.)
Upvotes: 2