Hopefully this is not the late-night effect, but I'm stumped by a very simple problem:
def test_getattr(v0):
v1 = "test1"
v2 = "test2"
v3 = "test3"
for k, v in locals().items():
print(k, v)
print(getattr(locals(), 'v1'))
test_getattr("test0")
The output gives the locals() dict items as expected:
v0 test0
v3 test3
v1 test1
v2 test2
But then dies with:
AttributeError: 'dict' object has no attribute 'v1'
v1 clearly is in the locals() 'dict', per the initial output, but then getattr() insists otherwise.
This is my first need to use locals(), but every bit of documentation I can find suggests this should work. What am I missing?
Edit/Update: Many thanks to @martijn for answer below. I managed to use dynamic local variables in getattr() by transiently assigning the local variables to a dummy class:
class Attr:
pass
def test_getattr(v0):
A = Attr()
A.v1 = "test1"
#etc
print(getattr(A, "v1"))
getattr()
retrieves attributes, not dictionary keys, and dictionary keys are not attributes. locals()
is just another dictionary, so use it as one:
print(locals()['v1'])
You'll otherwise only find the normal dictionary attributes on locals()
, such as keys
and items
and __len__
and __getitem__
:
>>> type(locals())
<type 'dict'>
>>> dir(locals())
['__class__', '__cmp__', '__contains__', '__delattr__', '__delitem__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'has_key', 'items', 'iteritems', 'iterkeys', 'itervalues', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values', 'viewitems', 'viewkeys', 'viewvalues']
>>> getattr(locals(), 'keys')
<built-in method keys of dict object at 0x10028f168>