The reason you get the error message is because getattr(myobj, "d['a']") looking for an attribute named d['a'] object, but it is not. Your attribute has a name d and a dictionary. When you have a link to a dictionary, you can access the elements in it.
mydict = getattr(myobj, "d") val = mydict["a"]
Or, as others have shown, you can combine this in one step (I showed it as two in order to better illustrate what is actually happening):
val = getattr(myobj, "d")["a"]
Your question implies that you think the dictionary elements in the object are "sub-elements" of the object. However, the element in the dictionary is different from the attribute of the object. ( getattr() also does not work with something like oa , it just gets one attribute of one object. If this object also wants to get one of its attributes, then another getattr() .)
You can easily write a function that moves along the attribute path (given in the string) and tries to resolve each name either as a dictionary key or attribute:
def resolve(obj, attrspec): for attr in attrspec.split("."): try: obj = obj[attr] except (TypeError, KeyError): obj = getattr(obj, attr) return obj
The main idea here is that you take a path and for each component of the path, try to find either an element in the container or as an attribute of an object. When you get to the end of the path, return what you have. Your example will resolve(myobj, "da")
source share