Python列表抽象

时间:2013-07-29 00:43:47

标签: python list abstraction

我有一个清单:

my_list = [a,b,c]

此列表中的所有元素都是我使用常用​​方法创建的对象:“play”

我想做这样的事情:

my_list.play()

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

这样的事情:

my_list.close()

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

我该怎么做?

4 个答案:

答案 0 :(得分:2)

子类化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

答案 1 :(得分:1)

map()应该做的伎俩

试试这个:

map(MyListClass.play,my_list)

map()有两个参数,一个函数和一个iterable,如上所示。

答案 2 :(得分: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()

答案 3 :(得分:0)

另一种变体:

playme = lambda x: x.play()
map(playme, list_goes_here)