在课堂上运行所有功能

时间:2016-05-06 15:03:51

标签: python class

我试图在我的课程中运行所有的功能,而不是单独输入它们。

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个函数。

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

5 个答案:

答案 0 :(得分:4)

您可以获取实例的所有“公开”方法的列表:

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语义,如果感兴趣,可以阅读that

答案 1 :(得分:4)

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

更新

正如Tadhg评论的那样,inspect.ismethod似乎是最好的选择。这是一些示例代码:

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

答案 2 :(得分:3)

这是解决此问题的最简单方法,也可以在其中进行更改。

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

答案 3 :(得分:1)

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

您最好定义一个您想要自己运行的方法列表。 E.g:

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

答案 4 :(得分:0)

虽然我不特别建议在对象上调用 all 方法,因为只要添加一些需要参数的方法就会失败,你可以使用装饰器标记代表的方法一个测试用例,然后搜索所有具有所述标签的那些:

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)