关于python:在类中运行所有函数

Run all functions in class

我正在尝试运行我的类中的所有函数,而不单独键入它们。

1
2
3
4
5
6
7
8
9
10
class Foo(object):
    def __init__(self,a,b):
        self.a = a
        self.b=b

    def bar(self):
        print self.a

    def foobar(self):
        print self.b

我想这样做,但是使用一个循环,因为我的实际类有大约8-10个函数。

1
2
3
x = Foo('hi','bye')
x.bar()
x.foobar()


可以使用dir()__dict__遍历对象的所有属性。您可以使用isinstance()types.FunctionType来判断哪些是函数。只要调用任何函数。

更新

正如塔德赫所评论的,江户十一〔六〕似乎是最好的选择。下面是一些示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import inspect
from itertools import ifilter


class Foo(object):
    def foo1(self):
        print('foo1')

    def foo2(self):
        print('foo2')

    def foo3(self, required_arg):
        print('foo3({!r})'.format(required_arg))

f = Foo()
attrs = (getattr(f, name) for name in dir(f))
methods = ifilter(inspect.ismethod, attrs)
for method in methods:
    try:
        method()
    except TypeError:
        # Can't handle methods with required arguments.
        pass


这是解决这个问题的最简单的方法,而且可以灵活地进行更改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import threading
from threading import Thread

class ClassName():
    def func1(self):
        print ('2')

    def func2(self):
        print ('3')

    def runall(self):
        if __name__ == '__main__':
            Thread(target = self.func1).start()
            Thread(target = self.func2).start()
run = ClassName()
run.runall() # will run all the def's in the same time


您可以获取实例的所有"public"方法的列表:

1
2
3
4
5
x = Foo('hi','bye')

public_method_names = [method for method in dir(x) if callable(getattr(x, method)) if not method.startswith('_')]  # 'private' methods start from _
for method in public_method_names:
    getattr(x, method)()  # call

了解更多关于getattr的信息实际上,python没有publicprivate语义,如果您感兴趣,可以阅读


虽然我意识到这不是你所要求的,但我认为你所要求的(执行所有方法)通常是一个坏主意,因为对象的API不是对象内部的。(例如,为了使用类,用户必须编写功能(即您所要求的功能)。

你最好定义一个你想自己运行的方法列表。例如。:

1
2
3
exec_methods = ["bar","foobar"]
for method in exec_methods:
    getattr(x, method)()

虽然我并不特别建议调用对象上的所有方法,因为一旦添加了一些需要参数的方法,它显然会失败,您可以使用一个修饰器来标记表示测试用例的方法,然后搜索具有上述标签的所有方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
def tester_method(f):
    f._is_for_test = True #add an arbitrary attribute to the function, completely supported for exactly this reason.
    return f

def call_all_tester_methods(x):
   """finds all attributes with a ._is_for_test attribute of their
own and calls all of them in no guaranteed order"""

    methods = {}
    for name in dir(x):
        attr = getattr(x,name)
        if getattr(attr,"_is_for_test",False):
            methods[name] = attr
    for name,method in methods.items():
        #print("calling: {}".format(name))
        method()

class Foo(object):
    def __init__(self,a,b):
        self.a = a
        self.b=b

    @tester_method
    def bar(self):
        print(self.a)

    @tester_method
    def foobar(self):
        print(self.b)

    def othermethod_not_for_test(self,arg):
        return self.a + arg #this is not included in the test case

obj = Foo('hi','bye')
call_all_tester_methods(obj)