3

So in playing around with getattr in my code I discovered the following:

myVariable = foo.A.bar

works...but something like this:

B = "A"
myVariable = getattr(foo, B + ".bar")

returns an error that foo does not contain an attribute A.bar. Where am I going wrong? Thanks!

MattyZ
  • 1,541
  • 4
  • 24
  • 41

2 Answers2

12

Because there is no attribute A.bar on foo. Attribute bar is a part of the object pointed to by A, which is an attribute of foo. You need either

getattr(foo.A, "bar")

or

getattr(getattr(foo, 'A'), 'bar')

The generic code for accessing deep attributes is to split on the dot, and go until the last part is found (I'm writing from memory, not tested):

def getattr_deep(start, attr):
    obj = start
    for part in attr.split('.'):
        obj = getattr(obj, part)
    return obj

getattr_deep(foo, 'A.bar')
Cat Plus Plus
  • 125,936
  • 27
  • 200
  • 224
2

The equivalent of :

myVariable = foo.A.bar 

using getattr would take 2 steps.

aObject = getattr(foo, 'A') 
myVariable = getattr(aobject, 'bar')

doing it in your way `myVariable = getattr(foo, B + ".bar") means 'myVariable = getattr(foo, "B.bar")' getAttr now lookups the string "B.bar" which obviously does not exist.

Stephan
  • 3,679
  • 3
  • 25
  • 42