如何在名称和类型相同的多个对象上调用方法?

3
我该如何简化这段代码?最好将它放入循环中或变成一行代码。
object1.callMethod()  
object2.callMethod()  
object3.callMethod()  

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

我知道我可以将对象放入列表并遍历该列表,但是这仍然需要两个单独的循环和两个单独的列表。是否有任何方法可以创建一个[1,2,3]的单一列表,并使用它来区分每种类型的三个不同对象,因为数字也包含在对象名称中?


2
有一些方法可以做你所问的事情,但你能展示这些类/函数的实际代码吗?那将有助于提供有用的答案。 - SuperBiasedMan
这是我寻求的唯一简化方式 - 如果这可行,那就是我所需要的。如果我将所有这些类和函数的代码都放在这里,那将会有数百行之多。 - Jonah Yousif
您可能也会对operator.methodcaller感兴趣。 - Patrick Haugh
相关链接:如何创建可变变量?,尤其是TigerhawkT3的回答。简而言之:一开始就使用列表。 - wjandrea
3个回答

2
你可以使用词典方法:
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)

这假定你正在使用实例方法。对于静态/类方法,您需要调整传递给方法的对象。
我不确定是否有任何优雅的方法不涉及预定义多个(或组合)列表和字典并循环执行它,因为您需要明确哪个对象运行哪些方法,无论如何都需要定义。
理想情况下,如果您有多个相似的同一类对象,您可能会选择从一开始就在列表中实例化它们:
# 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}

然后,将它们作为一组进行操作就变得很容易:
for foo in foos:
    foo.foo_method()

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

虽然仍然可以轻松地引用对象本身:

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

1
getattr(obj, method_name)()

如果所有的方法和对象名称都是语义化的,你可以使用getattr根据一个字符串变量引用该方法,然后使用()调用它。
objects = [object1, object2, object3]
for obj in objects:
    getattr(obj, method_name)()

如果你想要并行存储对象/方法,请使用zip
objects = [object1, object2, object3]
methods = ['method1name', 'method2name', 'method3name']
for obj, method in zip(objects, methods):
    getattr(obj, method)()

-2
你可以使用eval函数:
for i in range(1, 4):
    eval("object%d" % i).callMethod()
    eval("difObject%d" % i).callDifMethod()

我不会使用这个。它确实能工作,但是它会让代码变得混乱。如果有人将其应用到一个不同的情况下,其中i来自不安全的用户输入,那么这就存在安全风险。我认为在这个答案中添加一个警告会很有帮助。 - wjandrea
1
没有理由在有更安全、更具体的替代方案可用时建议使用eval - chepner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接