Issue 1387650: weird behavior when assigning locals() to a variable (original) (raw)
Issue1387650
Created on 2005-12-22 00:04 by sambayer, last changed 2022-04-11 14:56 by admin. This issue is now closed.
Messages (4) | ||
---|---|---|
msg27123 - (view) | Author: Samuel Bayer (sambayer) | Date: 2005-12-22 00:04 |
Tried this on Python 2.3.3, under Redhat Linux Enterprise 3, and on Python 2.3.5, under MacOS X 10.4.3. Don't have access to 2.4 anywhere, so I can't test it, but I took a look at the bug queue and can't find any reference to this problem. The following function yields a KeyError when run: def foo(): b = locals() c = 5 print b["c"] The following function does not: def foo(): b = locals() c = 5 locals() print b["c"] There's no typo there. After referencing locals() again, without updating the value of b, the printout works. Note that b and locals(), as I believe is intended, are identical: def foo(): b = locals() c = 5 print id(b) print b.has_key() print id(locals()) print b.has_key() yields, when run: >>> foo() 285984 False 285984 True This has GOT to be a bug. | ||
msg27124 - (view) | Author: Samuel Bayer (sambayer) | Date: 2005-12-22 00:25 |
Logged In: YES user_id=40146 OK, it doesn't got to be a bug. After staring at the documentation for locals(), I realize that locals() is only updated when it's called again. So it's not a bug, but it is a little odd. It's the only namespace-like object you can't reliably use as a format string argument. Consider the following: >>> b = globals() >>> c = 5 >>> print "%(c)d" % b This prints the expected value. Ditto this: >>> Class Foo: pass >>> a = Foo(); b = a.__dict__ >>> a.c = 5 >>> print "%(c)d" % b Only with locals(), inside a function, does this pattern fail. I imagine it would be expensive to make work, though. Never mind... | ||
msg27125 - (view) | Author: Neal Norwitz (nnorwitz) * ![]() |
Date: 2005-12-22 05:48 |
Logged In: YES user_id=33168 If you have suggestions for how we can improve the doc, let us know. I'll close this bug report since you seem to agree it's not a bug. | ||
msg27126 - (view) | Author: Samuel Bayer (sambayer) | Date: 2005-12-22 13:24 |
Logged In: YES user_id=40146 This morning, as I thought about it some more, I had some vain hope that the __getitem__ method of that particular dictionary could be updated to refresh the dictionary, but after trolling through the source a little, I see that it's really just a regular dictionary, and it doesn't know anything about where it came from. Would it be dangerous to add the current stack frame to the locals() dictionary as a value like __frame___? Perhaps that would screw up the garbage collection by adding a circular reference. In any case, the current documentation for locals() reads: "Update and return a dictionary representing the current local symbol table. Warning: The contents of this dictionary should not be modified; changes may not affect the values of local variables used by the interpreter." I'd say something like "Update and return a dictionary representing the current local symbol table. Warnings: The contents of this dictionary should not be modified; changes may not affect the values of local variables used by the interpreter. Also, this dictionary is not guaranteed to be synchronized with the actual local environment; if the local symbol table changes between the time you retrieve the value of locals() and the time you use it, you won't see the changes." |
History | |||
---|---|---|---|
Date | User | Action | Args |
2022-04-11 14:56:14 | admin | set | github: 42714 |
2005-12-22 00:04:14 | sambayer | create |