Skip to content Skip to sidebar Skip to footer

Getting An Attribute Of Grandparent Class Using Getattr

I'm trying to access an instance attribute (inst_baseA / inst_baseB) of Base class from an instance of ClassB, depending on an attribute of the instance (self.x of object ClassB).

Solution 1:

There's operator.attrgetter, but it's really not meant for this kind of thing, so the syntax is pretty awkward:

>>> operator.attrgetter('node.inst_base')(b)
'base'

But this is really quite unintuitive, so to avoid confusing people who read your code, it's probably better to roll your own multi-getattr instead:

defget_multi_attr(obj, attrs):
    for attr in attrs.split('.'):
        obj = getattr(obj, attr)
    return obj
>>> get_multi_attr(b, 'node.inst_base')
'base'

Solution 2:

According to [Python]: getattr(object, name[, default]):

Return the value of the named attribute of object. name must be a string. If the string is the name of one of the object’s attributes, the result is the value of that attribute. For example, getattr(x, 'foobar') is equivalent to x.foobar.

node.inst_base is not an attribute of b, but:

  • node is an attribute of b
  • inst_base is an attribute of b.node

So, you need one getattr call for each "nesting" level.

Considering that I've pasted your code in the interpreter's interactive window:

>>> getattr(b, 'node.inst_base')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'ClassB'object has no attribute 'node.inst_base'
>>>
>>> getattr(getattr(b, "node", None), "inst_base", None)
'base'

Or, to take things further, you can create a getter that works with "nested" attribute names:

>>>defgetattr_nested(obj, nested_attr):...    attrs = nested_attr.split(".")...    ret = obj...for attr in attrs:...            ret = getattr(ret, attr, None)...if ret isNone:...returnNone...return ret...>>>>>>getattr_nested(b, "node.inst_base")
'base'
>>>getattr_nested(b, "node.inst_base2")>>>getattr_nested(b, "node")
<__main__.Base object at 0x0000021A2A593D30>

But that's probably highly inefficient (and also, doesn't handle corner cases), and you'd better use @Aran-Fey's suggestion.

Post a Comment for "Getting An Attribute Of Grandparent Class Using Getattr"