在Python中如何编写这样一个函数,它将使用给定的前缀调用当前文件中的所有函数?
例如:
def prepare(self):
# ??? to call prepare_1, prepare_2
def prepare_1(self):
def prepare_2(self):
如何编写prepare
以便它会调用以prepare_
开头的所有函数?
答案 0 :(得分:8)
使用globals访问全局命名空间,dict.items迭代它,callable和str.startswith以确定该函数具有您希望的名称并且可以调用:
def prepare(self):
for key, value in globals().items():
if callable(value) and key.startswith('prepare_'):
value()
def prepare_1(self):print 1
def prepare_2(self):print 2
答案 1 :(得分:5)
如果这些函数是类的方法,请使用dir(self)
列出self
的所有属性。
class C:
def prepare(self):
print(dir(self))
for name in dir(self):
if name.startswith('prepare_'):
method = getattr(self, name)
method()
def prepare_1(self):
print('In prepare_1')
def prepare_2(self):
print('In prepare_2')
C().prepare()
输出:
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'prepare', 'prepare_1', 'prepare_2']
In prepare_1
In prepare_2
更新:如果你想调用C类以外的方法:
obj = C()
for name in dir(obj):
if name.startswith('prepare_'):
m = getattr(obj, name)
print(m)
m()
输出:
<bound method C.prepare_1 of <__main__.C object at 0x7f347c9dff28>>
In prepare_1
<bound method C.prepare_2 of <__main__.C object at 0x7f347c9dff28>>
In prepare_2
答案 2 :(得分:1)
有人要求,所以这是一个快速的黑客攻击:
import functools
class FunctionGroup(object):
"""
Defines a function group as a list of functions that can be
executed sequentially from a single call to the function group.
Use
@func_group.add
def my_func(...):
...
to add functions to the function group.
`func_group(...)` calls the added functions one by one.
It returns a list of the return values from all evaluated functions.
Processing terminates when one of the function raises an
exception and the exception is propagated to the caller.
"""
def __init__(self):
self.funcs = []
def add(self, func):
self.funcs.append(func)
return func
def __call__(self, *args, **kwargs):
return [
func(*args, **kwargs) for func in self.funcs
]
prepare_group = FunctionGroup()
请注意,__call__()
实现相当原始,无法处理异常。
用法示例:
@prepare_group.add
def prepare_1():
print "prep 1"
@prepare_group.add
def prepare_2():
print "prep 2"
prepare_group()
当然可能滥用来调用方法:
class C(object):
def m(self):
pass
c = C()
func_group.add(c.m)