除了指定的方法之外,调用列表中的方法

时间:2018-03-21 04:30:14

标签: python python-3.x

我有一个方法列表,我可以用另一种方法一次调用所有方法。

如何在列表中省略某些项目(或方法)的同时调用包含所有项目的方法?我现在可以指定一个遗漏。我不确定如何不止一个。以下是我的工作内容:

class SomeClass:
    def method_a(self):
        print('method_a')

    def method_b(self):
        print('method_b')

    def method_c(self):
        print('method_c')

    def method_runner(self, skip_name='' ):
        for m in [self.method_a, self.method_b, self.method_c]:
            if m.__name__ != skip_name:
                m()

现在我可以这样做:

>>> some_obj = SomeClass()
>>> some_obj.method_runner('')
method_a
method_b
method_c
>>> some_obj.method_runner('method_a')
method_b
method_c
>>> some_obj.method_runner('method_b')
method_a
method_c

有没有办法做这样的事情?

class SomeClass:
    def method_a(self):
        print('method_a')

    def method_b(self):
        print('method_b')

    def method_c(self):
        print('method_c')

    def method_runner(self, skip_name='', skip_name2='', skip_name3=''):
        for m in [self.method_a, self.method_b, self.method_c]:
            options = [skip_name, skip_name2, skip_name3]
            for o in options:
                if m.__name__ != o:
                    m()

并指定多种方法来获得结果,例如:

>>> some_obj.method_runner('method_a', 'method_c')
method_b

2 个答案:

答案 0 :(得分:2)

你可以这样做:

def method_runner(self, *skip_list):
        for m in [self.method_a, self.method_b, self.method_c]:
            if m.__name__ not in skip_list:
                m()

*表示不同数量的参数。

如果您不想手动输入方法名称,可以使用:

def method_runner(self, *skip_list):
    methods = [f for f in map(lambda x: getattr(self,x), dir(self)) if callable(f) and f.__name__ != 'method_runner']
    for m in methods:
        if m.__name__ not in skip_list:
            m()

答案 1 :(得分:2)

是的,至少有直截了当的方法。最直接的是参数接受要跳过的对象容器:

def method_runner(self, skipnames):
    for m in [self.method_a, self.method_b, self.method_c]:
        if m.__name__ not in skipnames:
            m()

您可以通过传递适当的容器来调用(在这种情况下为set,但listtuple可能会这样做:

SomeClass().method_runner({'method_a', 'method_c'})

但它听起来就像你更喜欢使用可变长度的参数:

def method_runner(self, *skipnames):
    for m in [self.method_a, self.method_b, self.method_c]:
        if m.__name__ not in skipnames:
            m(self)

然后你可以这样打电话:

SomeClass().method_runner('method_a', 'method_c')

但是,skipnames现在将始终是一个元组,可能没有您需要的性能特征。

根据@ChristianDean的建议,您可能希望将方法列表设为类变量:

In [7]: class SomeClass:
   ...:     def method_a(self):
   ...:         print('method_a')
   ...:
   ...:     def method_b(self):
   ...:         print('method_b')
   ...:
   ...:     def method_c(self):
   ...:         print('method_c')
   ...:
   ...:     _my_methods = method_a, method_b, method_c
   ...:
   ...:     def method_runner(self, skipnames):
   ...:         for m in self._my_methods:
   ...:             if m.__name__ not in skipnames:
   ...:                 m(self)
   ...:

In [8]: SomeClass().method_runner({'method_a', 'method_c'})
method_b

请注意,您必须手动将self传递给该功能,因为它不是一种方法!