4

我有一个清单:

my_list = [a,b,c]

此列表中的所有元素都是我使用通用方法创建的对象:“播放”

我想做这样的事情:

my_list.play()

这将触发列表中每个对象的播放方法。

像这样的东西:

my_list.close()

也应该工作(“关闭”也是一种常用方法)。

我该怎么做呢?

4

4 回答 4

3

子类化list

如果你坚持,你可以继承list

class ListContainer(list):
    def play(self, *args, **kwargs):
        for item in self:
            item.play(*args, **kwargs)
    def close(self, *args, **kwargs):
        for item in self:
            item.close(*args, **kwargs)

(顺便说一句。您将传递给容器方法的任何内容都将传递给每个项目,除非发生错误)

哪个会这样工作:

>>> class Sound(object):
    def __init__(self, name):
        self.name = name
    def play(self):
        print('Playing %s' % (self.name,))
    def close(self):
        print('Closing %s' % (self.name,))


>>> container = ListContainer([Sound('a'), Sound('b'), Sound('c')])
>>> container.play()
Playing a
Playing b
Playing c
>>> container.close()
Closing a
Closing b
Closing c

更好的解决方案

但你不应该。更好的解决方案是明确地做到这一点:

container = [a, b, c]
# ...
for item in container:
    item.play()

请记住,显式优于隐式。这就是为什么最好遍历项目并一一调用它们的原因。

更糟糕的解决方案

如果你想隐式调用列表项的方法,有一种方法;)下面是首先搜索list属性的实现,如果没有找到,将假定它是一个方法并调用列表中的每个项目:

class BadImplicitContainer(list):
    def __getattr__(self, name):
        def _wrapper(*args, **kwargs):
            for item in self:
                getattr(item, name)(*args, **kwargs)
        return _wrapper

这就是它在前面片段中的示例中的行为方式:

>>> container = BadImplicitContainer([Sound('bad'), Sound('Bad'), Sound('BAD')])
>>> container.play()
Playing bad
Playing Bad
Playing BAD
于 2013-07-29T00:58:35.450 回答
1

map()应该做的伎俩

尝试这个:

map(MyListClass.play,my_list)

map()接受两个参数,一个函数和一个可迭代对象,如上所示。

于 2013-07-29T00:56:35.120 回答
1

恐怕您不能在列表中执行此操作,因为它们没有属性。如果你愿意,你必须继承它。

>>> class MyList(list):
...     def play(self):
...             for each in self:
...                     each.play()
...     def close(self):
...             for each in self:
...                     each.close()

但也许一份清单就足够了:

for each in alist:
    each.play()
于 2013-07-29T00:56:38.127 回答
0

另一种变体:

playme = lambda x: x.play()
map(playme, list_goes_here)
于 2013-07-29T02:41:40.823 回答