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() |
可以使用
正如塔德赫所评论的,江户十一〔六〕似乎是最好的选择。下面是一些示例代码:
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没有
虽然我意识到这不是你所要求的,但我认为你所要求的(执行所有方法)通常是一个坏主意,因为对象的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) |