如何对一系列对象调用同一方法?
假设有这样的代码:
class Base:
def start(self):
pass
def stop(self)
pass
class A(Base):
def start(self):
... do something for A
def stop(self)
.... do something for A
class B(Base):
def start(self):
def stop(self):
a1 = A(); a2 = A()
b1 = B(); b2 = B()
all = [a1, b1, b2, a2,.....]
现在我想对列表中的每个对象调用 start 和 stop 方法(可能还有其他方法)。有没有什么简单优雅的方法来做到这一点,而不是写一堆函数,比如:
def start_all(all):
for item in all:
item.start()
def stop_all(all):
10 个回答
42
看起来应该有更符合Python风格的方法来做这个,但我还没找到。
有时候我会用“map”这个函数,如果我想对一堆对象调用同一个函数(不是方法):
map(do_something, a_list_of_objects)
这样可以替代一大堆像这样的代码:
do_something(a)
do_something(b)
do_something(c)
...
不过也可以用普通的“for”循环来实现:
for obj in a_list_of_objects:
do_something(obj)
缺点是:a) 你用“map”创建了一个列表作为返回值,但这个列表其实没用就被丢掉了;b) 可能比简单的循环更让人困惑。
你也可以用列表推导式,但这也有点过分(同样是创建了一个没用的列表):
[ do_something(x) for x in a_list_of_objects ]
对于方法,我想这两种方式都可以用(但也有同样的问题):
map(lambda x: x.method_call(), a_list_of_objects)
或者
[ x.method_call() for x in a_list_of_objects ]
所以,实际上,我觉得普通的(但有效的)“for”循环可能是最好的选择。
201
这个方法可以用
all = [a1, b1, b2, a2,.....]
map(lambda x: x.start(),all)
简单的例子
all = ["MILK","BREAD","EGGS"]
map(lambda x:x.lower(),all)
>>>['milk','bread','eggs']
还有在Python3中的用法
all = ["MILK","BREAD","EGGS"]
list(map(lambda x:x.lower(),all))
>>>['milk','bread','eggs']
8
*_all() 函数非常简单,对于一些方法,我干脆就自己写函数。如果你有很多功能完全相同的函数,可以写一个通用的函数:
def apply_on_all(seq, method, *args, **kwargs):
for obj in seq:
getattr(obj, method)(*args, **kwargs)
或者可以创建一个函数工厂:
def create_all_applier(method, doc=None):
def on_all(seq, *args, **kwargs):
for obj in seq:
getattr(obj, method)(*args, **kwargs)
on_all.__doc__ = doc
return on_all
start_all = create_all_applier('start', "Start all instances")
stop_all = create_all_applier('stop', "Stop all instances")
...