Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert string to class sub-attribute with Python

I know I can get a Class's attributes with a string like this:

object.attribute = 'foo'
x = 'attribute'
getattr(object, x)
>>> 'foo'

Is there a way to "go deeper" into the object's attributes with a string? In other words, if my object contains another object, how can I get the the sub-object's attributes with a string? For example:

object.object.attribute
like image 494
MFB Avatar asked Jul 04 '12 03:07

MFB


People also ask

How do I convert a string to an object in Python?

Use the json.loads() function. The json. loads() function accepts as input a valid string and converts it to a Python dictionary. This process is called deserialization – the act of converting a string to an object.

How do you convert a string to a variable in Python?

Instead of using the locals() and the globals() function to convert a string to a variable name in python, we can also use the vars() function. The vars() function, when executed in the global scope, behaves just like the globals() function.

What is Setattr in Python?

The setattr() function sets the value of the specified attribute of the specified object.


2 Answers

The operator.attrgetter function does this:

class Foo: pass
f = Foo()
f.bar = Foo()
f.bar.baz = Foo()
f.bar.baz.quux = "Found me!"

import operator
print operator.attrgetter("bar.baz.quux")(f)     # prints "Found me!"
like image 160
Ned Batchelder Avatar answered Nov 01 '22 11:11

Ned Batchelder


I love the recipe given in this link (actually the comment is even better though)

Example borrowed from Claudiu's answer (which is great too):

class Foo: pass
f = Foo()
f.bar = Foo()
f.bar.baz = Foo()
f.bar.baz.quux = "Found me!"

A recursive getattr that follows dots:

>>> rgetattr = lambda o,a: reduce(getattr, a.split('.'), o)
>>> rgetattr(f, 'bar.baz.quux')
'Found me!'

The non-lambda version being:

def rgetattr(obj, attr):
    return reduce(getattr, attr.split('.'), obj)
like image 22
jdi Avatar answered Nov 01 '22 11:11

jdi