Python: How to get attribute of attribute of an object with getattr?

Question:

How do I evaluate

a = myobject.id.number

and return None if it myobject is None

with built-in getattr? Maybe getattr(myobject, "id.number", None)?

Asked By: alwbtc

||

Answers:

A slightly over generic solution keeping in view all members:

if myobject and myobject.id and myobject.id.number:
    a = myobject.id.number
else:
    a = None
Answered By: sharjeel
getattr(getattr(myobject, "id", None), "number", None)

should work.

Answered By: siddharthlatest

Here’s a one-liner

a = myobject is not None and myobject.id.number or None

It doesn’t check whether id is None, but that wasn’t part of the original question.

Answered By: tdelaney
return myobject.id.number if myobject else None
Answered By: Hyperboreus

This should scale well to any depth:

reduce(lambda obj, attr : getattr(obj, attr, None), ("id","num"), myobject)

my favorites are

from functools import reduce
try:
  a = reduce(getattr, ("id", "number"), myobject)
except AttributeError:
  a = None

or

from operator import attrgetter
try:
  a = attrgetter('id.number')(myobject)
except AttributeError:
  a = None
Answered By: Dash Winterson

I use the following function which does it for any level.

def Resolve(object, attribute:str):
  """
  Resolve attribute of an object.
  """
  attribute_list = attribute.split(".")
  obj = object
  try:
    for att in attribute_list:
      obj = getattr(obj, att)
  except AttributeError:
    obj = None
    
  return obj

To use it you write:

a = Resolve(myobject, 'id.number')

The code simply splits the string using the the period character and loops through the attributes. If you had another level say `myobject.id.number.another’ you would use:

a = Resolve(myobject, 'id.number.another')
Answered By: R Walser
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.