如何为对象列表调用相同的方法?

时间:2010-04-21 10:20:37

标签: python

假设代码如下:

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):

7 个答案:

答案 0 :(得分:142)

这将有效

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']

答案 1 :(得分:26)

似乎会有更多的Pythonic方法,但我还没有找到它。

如果我在一堆对象上调用相同的函数(不是方法),我有时会使用“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”循环可能是你最好的选择。

答案 2 :(得分:16)

方法

for item in all:
    item.start()

简单,易读,简洁。这是Python为此操作提供的主要方法。如果有帮助的话,你当然可以将它封装在一个函数中。为一般用途定义一个特殊功能可能不仅仅是写出for循环。

答案 3 :(得分:7)

也许是map,但既然你不想列表,你可以自己编写......

def call_for_all(f, seq):
    for i in seq:
        f(i)

然后你可以这样做:

call_for_all(lamda x: x.start(), all)
call_for_all(lamda x: x.stop(), all)
顺便说一句,所有都是内置函数,不要覆盖它; - )

答案 4 :(得分:3)

让@Ants Aasmas更进一步,您可以创建一个包含任何方法调用的包装器并将其转发到给定列表的所有元素:

class AllOf:
    def __init__(self, elements):
        self.elements = elements
    def __getattr__(self, attr):
        def on_all(*args, **kwargs):
            for obj in self.elements:
                getattr(obj, attr)(*args, **kwargs)
        return on_all

然后可以像这样使用该类:

class Foo:
    def __init__(self, val="quux!"):
        self.val = val
    def foo(self):
        print "foo: " + self.val

a = [ Foo("foo"), Foo("bar"), Foo()]
AllOf(a).foo()

产生以下输出:

foo: foo
foo: bar
foo: quux!

通过一些工作和独创性,可能还可以增强处理属性(返回属性值列表)。

答案 5 :(得分:2)

* _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")
...

答案 6 :(得分:2)

从Python 2.6开始,有一个operator.methodcaller函数。

因此,您可以获得更优雅(更快捷)的东西:

from operator import methodcaller

map(methodcaller('method_name'), list_of_objects)