调用类中所有以某个前缀开头的方法

3 投票
4 回答
1587 浏览
提问于 2025-04-18 01:59

假设我们有一个这样的类:

class Test(object):

   def __init__(self):
      pass

   def fetch_a(self):
      print "a"

   def fetch_b(self):
      print "b"

我想在init函数中调用这个类里所有以"fetch"开头的函数。请问我该怎么做呢?

4 个回答

1

你可以试试用 dir 命令:

class Test(object):

   def __init__(self):
        for name in dir(Test):
            if len(name)>4 and name[:5] == "fetch":
                eval("self." + name + "()")

   def fetch_a(self):
      print "a"

   def fetch_b(self):
      print "b"


z = Test()
3

所有的回答都假设带有 fetch 的东西都是一个方法;但这并不能保证。看看这个例子:

class Foo(object):
    fetch_a = 'hello'

    def fetch_b(self):
        return 'b'

你会遇到 TypeError: 'str' object is not callable 的错误:

>>> a = Foo()
>>> for i in dir(a):
...     if i.startswith('fetch'):
...         print(getattr(a, i)())
...
Traceback (most recent call last):
  File "<stdin>", line 3, in <module>
TypeError: 'str' object is not callable

你还需要检查这个属性是否是一个方法。因为方法实现了 __call__,你可以在检查时用这个:

>>> for i in dir(a):
...     if i.startswith('fetch') and hasattr(getattr(a, i), '__call__'):
...         print(getattr(a, i)())
...
b

你也可以使用 callable()

>>> for i in dir(a):
...     if i.startswith('fetch') and callable(getattr(a, i)):
...         print(getattr(a, i)())
...
b

这个方法是在 Python 2.6 中引入的,在 Python 3.0 中被移除,然后在 Python 3.2 中又重新加入。所以要注意你的 Python 版本。

还有一种方法是使用 isfunction,这个来自于 inspect 模块,它是在 Python 2.1 中引入的:

>>> bar = lambda x: x
>>> callable(bar)
True
>>> import inspect
>>> inspect.isfunction(bar)
True
3

我会这样做:

def __init__(self):
    wanted = [m for m in dir(Test) if m.startswith('fetch') and 
                                      hasattr(getattr(self, m), '__call__')]
    for at in wanted:
        end = getattr(self, at)()
7

你可以这样做:

class Test(object):
    def __init__(self):
       for i in dir(self):
           if i.startswith('fetch'):
               result = getattr(self, i)()

    def fetch_a(self):
       print "a"

    def fetch_b(self):
       print "b"

>>> a = Test()
a
b
>>>

[更新]

如果你只想调用那些以 fetch 开头的方法,而不想调用变量的话,这样做就可以了:

class Test(object):
    def __init__(self):
       for i in dir(self):
           result = getattr(self, i)
           if i.startswith('fetch') and hasattr(result, '__call__'):
               result()

撰写回答