0

I have object1 which has many sub-objects in it. These sub-objects are accessed in the form object1.subobject. I have a function which returns a list of sub-objects of the original object. All I would like to do is iterate through the list and access each sub-object. Something like this:

temp_list = listSubChildren(object1)  #Get list of sub-objects
for sub_object in temp_list:          #Iterate through list of sub-objects
    blah = object1.sub-object         #This is where I need help 
    #Do something with blah           #So that I can access and use blah

I looked at similar questions where people used dictionaries and getattr but couldn't get either of those methods to work for this.

5
  • What is the type of the objects in temp_list? Also, you probably need to change sub-object to sub_object as the former is a SyntaxError I think ... Commented Jan 24, 2013 at 14:04
  • You need to provide an example, as I would use getattr for this problem. I cannot see why this should not work... Commented Jan 24, 2013 at 14:06
  • So you would use blah = object1.getattr(object1,sub_object) ? Commented Jan 24, 2013 at 14:07
  • 1
    @BloonsTowerDefence -- nope. getattr is a builtin function, not an instance method -- That one would be __getattr__, but don't call that directly here ... Commented Jan 24, 2013 at 14:09
  • What do you mean by 'sub-objects'? Do you mean instances of the object or a sub-class of the class? Commented Jan 24, 2013 at 14:13

3 Answers 3

6

It seems to me that if your listSubChildren method is returning strings as you imply, you can use the builtin getattr function.

>>> class foo: pass
... 
>>> a = foo()
>>> a.bar = 1
>>> getattr(a,'bar')
1
>>> getattr(a,'baz',"Oops, foo doesn't have an attrbute baz")
"Oops, foo doesn't have an attrbute baz"

Or for your example:

for name in temp_list:
    blah = getattr(object1,name)

As perhaps a final note, depending on what you're actually doing with blah, you might also want to consider operator.attrgetter. Consider the following script:

import timeit
import operator

class foo(object):
    def __init__(self):
        self.a = 1
        self.b = 2
        self.c = 3

def abc(f):
    return [getattr(f,x) for x in ('a','b','c')]

abc2 = operator.attrgetter('a','b','c')

f = foo()
print abc(f)
print abc2(f)

print timeit.timeit('abc(f)','from __main__ import abc,f')
print timeit.timeit('abc2(f)','from __main__ import abc2,f')

Both functions (abc, abc2) do nearly the same thing. abc returns the list [f.a, f.b, f.c] whereas abc2 returns a tuple much faster, Here are my results -- the first 2 lines show the output of abc and abc2 respectively and the 3rd and 4th lines show how long the operations take:

[1, 2, 3]
(1, 2, 3)
0.781795024872
0.247200965881

Note that in your example, you could use getter = operator.attrgetter(*temp_list)

Sign up to request clarification or add additional context in comments.

5 Comments

The thing is that I need blah to equal object1.name ... so I would have object1.first, object1.second, object1.third ...
Which brings us back to my original question. What does listSubChildren actually return? If it returns an iterable like ["first","second","third"] then this will set blah to object1.first on the first pass, then object1.second, then object1.third ...
Yes it returns strings. Sorry for the confusion, this works indeed.
@BloonsTowerDefence -- I don't know what you plan on doing with listSubChildren, but you might want to also consider operator.attrgetter. It's pretty neat.
debates internally ... Should I post about f.__dict__[x] too? It's faster than getattr, but a lot uglier and not all classes have __dict__ ...
0

It should look something like this:

temp_list = [] 
for property_name in needed_property_names:
    temp_list.append(getattr(object1, property_name))

So, getattr is what you need.

Comments

0

Add this to the class that object1 is an instance of:

def getSubObjectAttributes(self):
    childAttrNames = "first second third".split()
    return [getattr(self, attrname, None) for attrname in childAttrNames]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.