有没有办法遍历并执行Python类中的所有函数?
我有
class Foo():
function bar():
pass
function foobar():
pass
与其像下面这样一个一个地执行每个函数:
x = Foo()
x.bar()
x.foobar()
有没有什么内置的方法可以按照它们在类中写的顺序,循环执行每个函数呢?
7 个回答
5
因为Python把一个类的方法(还有其他属性)存储在一个字典里,而字典本质上是没有顺序的,所以这是不可能的。
如果你不在乎顺序,可以使用这个类的 __dict__
:
x = Foo()
results = []
for name, method in Foo.__dict__.iteritems():
if callable(method):
results.append(method(x))
如果函数需要额外的参数,也没问题——只要把这些参数放在类的实例后面就行。
13
def assignOrder(order):
@decorator
def do_assignment(to_func):
to_func.order = order
return to_func
return do_assignment
class Foo():
@assignOrder(1)
def bar(self):
print "bar"
@assignOrder(2)
def foo(self):
print "foo"
#don't decorate functions you don't want called
def __init__(self):
#don't call this one either!
self.egg = 2
x = Foo()
functions = sorted(
#get a list of fields that have the order set
[
getattr(x, field) for field in dir(x)
if hasattr(getattr(x, field), "order")
],
#sort them by their order
key = (lambda field: field.order)
)
for func in functions:
func()
上面那个有趣的 @assignOrder(1)
这一行在 def bar(self)
之前,会导致以下事情发生:
Foo.bar = assignOrder(1)(Foo.bar)
assignOrder(1)
会返回一个函数,这个函数接收另一个函数,修改它(添加一个叫 order
的字段,并把它设置为 1
),然后返回这个修改后的函数。这个函数随后会被用在它装饰的那个函数上(这样它的 order
字段就被设置了);最终的结果会替换掉原来的函数。
这其实是一个更高级、更易读、更好维护的说法:
def bar(self):
print "bar"
Foo.bar.order = 1
10
不可以。你可以访问 Foo.__dict__
,然后依次调用里面的每个值(如果遇到不能调用的成员就捕获错误),但是调用的顺序是不固定的。
for callable in Foo.__dict__.values():
try:
callable()
except TypeError:
pass
这假设里面的函数都不需要参数,就像你举的例子那样。