How to call method on multiple objects with similar names and same type?

Viewed 828

How might I go about simplifying this code, preferably putting it into a loop or one line?

object1.callMethod()  
object2.callMethod()  
object3.callMethod()  

difObject1.callDifMethod()  
difObject2.callDifMethod()  
difObject3.callDifMethod()  

I know that I can put the objects in a list and iterate through that, however, that would still require two separate loops and two separate lists. Is there any way that I can make a singular list of [1,2,3] and use that to distinguish between the three different objects of each type, since the numbers are in the object names as well?

3 Answers
getattr(object, method_name)()

If all of the method and object names are generally semantic, you can use getattr to reference the method based on a string variable, and then call it with ().

objects = [object1, object2, object3]
for object in objects:
    getattr(object, method_name)()

If you want to run the objects/method in parallel, use zip.

objects = [object1, object2, object3]
methods = ['method1name', 'method2name', 'method3name']
for object, method in zip(objects, methods):
    getattr(object, method)()

You could use a dictionary approach:

methods = {cls1.method1: [cls1_obj1, cls1_obj2, cls1_obj3],
           cls1.method2: [cls1_obj4, cls1_obj5, cls1_obj6],
           cls2.method1: [cls2_obj1, cls2_obj2}

for method, objs in methods.items():
    for obj in objs:
        method(obj)

This assumes you are using an instance method though. For a static/class method you'll need to adjust the object being passed for the method.

I'm not sure there's anything elegant that doesn't involve predefining multiples (or combinations) of lists and dicts and loop over it, since you would need to be explicit in which object runs which methods, a definition is required either way.


Ideally, if you have multiple similar objects of the same class, you might opt to instantiate them in a list from the get go:

# Instead of this
object1 = Foo(1)
object2 = Foo(2)
object3 = Foo(3)
...

# do this
foos = [Foo(i) for i in range(3)]

# Or this
bars = {name: Bar(name) for name in list_of_names}

Then it becomes trivial to manipulate them in group:

for foo in foos:
    foo.foo_method()

for bar in bars.values():
    bar.bar_method()

While still easy to reference the object on its own:

foo[index].foo_method()
bar[key].bar_method()

You could use the eval function:

>>> for i in range(1,4):
>>>     eval("object%d" % i).callMethod()
>>>     eval("difObject%d" % i).callDifMethod()
Related