有没有办法循环并执行Python类中的所有函数?

cur*_*ous 9 python reflection class

我有

class Foo():
    function bar():
        pass

    function foobar():
        pass
Run Code Online (Sandbox Code Playgroud)

而不是逐个执行每个功能,如下所示:

x = Foo()
x.bar()
x.foobar()
Run Code Online (Sandbox Code Playgroud)

是否有一种内置的方法来循环并执行它们在类中编写的顺序中的每个函数?

bad*_*adp 10

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()
Run Code Online (Sandbox Code Playgroud)

@assignOrder(1)上面那条有趣的线条def bar(self)会触发这种情况:

Foo.bar = assignOrder(1)(Foo.bar)
Run Code Online (Sandbox Code Playgroud)

assignOrder(1)返回一个函数,它接受另一个函数,更改它(添加字段order并将其设置为1)并返回它.然后在它装饰的函数上调用该函数(其order字段因此设置); 结果取代了原来的功能.

这是一种更高级,更易读,更易于维护的说法:

  def bar(self):
    print "bar"
  Foo.bar.order = 1
Run Code Online (Sandbox Code Playgroud)

  • 如果可能的话尽量不要使用`eval`.像这样的东西应该有效:`[getattr(x,field)表示dir(x)中的字段,如果是hasattr(getattr(x,field),'order')]` (2认同)

Mat*_*hen 8

不可以.您可以访问Foo.__dict__并依次调用每个值(捕获不可调用成员的错误),但不保留订单.

for callable in Foo.__dict__.values():
    try:
        callable()    
    except TypeError:
        pass
Run Code Online (Sandbox Code Playgroud)

这假设没有一个函数采用参数,如在您的示例中.


Dan*_*l G 5

由于Python将类的方法(和其他属性)存储在字典中,这基本上是无序的,因此这是不可能的.

如果您不关心订单,请使用以下类__dict__:

x = Foo()
results = []
for name, method in Foo.__dict__.iteritems():
    if callable(method):
        results.append(method(x))
Run Code Online (Sandbox Code Playgroud)

如果函数需要额外的参数,这也适用 - 只需将它们放在类的实例之后.