我在设计构建抽象基类时遇到了问题。
我的类定义了一个Executor
,我想创建它的子项并添加更多功能。
在纸面上我希望我的执行者有两个操作步骤:
run
函数按顺序运行这些步骤。
关于Before-Execute
阶段,这可以包括在对象上调用多个函数 - >一些抽象函数和派生类中的一些其他附加函数。
我一直试图想出一种能够在Before-Execute
阶段调用函数的方法,而无需在每个派生类中重新定义before_execute
函数。
我实现这一目标的方式(我并不是非常喜欢)是通过定义一个成员列表before_execute_functions
,其中包含我想要在{{1}中调用的所有函数的名称舞台。
Before-Execute
函数遍历列表并按顺序调用每个函数。在派生类中,我可以将我想在before_execute
阶段调用的任何其他函数的名称添加到列表中。
代码如下所示:
Before-Execute
我可以使用它:
class Executor:
__metaclass__ = ABCMeta
def __init__(self):
self.before_execute_functions = ['get_script', 'get_input']
@abc.abstractmethod
def get_script(self):
pass
@abc.abstractmethod
def get_input(self):
pass
def before_execute(self):
#call each function in the list
for f in self.before_execute_functions:
if not getattr(self, f)():
return False
return True
@abc.abstractmethod
def execute(self):
pass
def run(self):
self.before_execute()
self.execute()
但我不喜欢我提出的解决方案,我想知道是否有任何方法可以向函数添加属性或标记。那么在我的class MyExecutor(Executor):
def __init__(self):
Executor.__init__(self)
self.before_execute_functions.append('my_other_function')
def get_script(self):
#do stuff
pass
def get_input(self):
#do stuff
pass
#An additional function I want called
#during the Before-Execute stage
def my_other_function():
#do stuff
pass
def execute(self):
#do stuff
pass
函数中,我可以使用例如调用所有函数。 before_execute
属性/标记。这将节省我必须管理成员列表。
这样的事情可能吗?或者任何人都可以想到更好的方法来实现这一目标?而且,如果我是个白痴,请不要犹豫告诉我!提前致谢! :)
答案 0 :(得分:2)
我会更明确地定义before_execute
:
class Executor(object):
__metaclass__ = ABCMeta
def before_execute(self):
#call each function in the list
return self.get_script() and self.get_input()
现在,如果用户想要添加更多操作,他们可以根据需要覆盖before_execute
调用超类的方法:
class MyExecutor(Executor):
def before_execute(self):
result = super(MyExecutor, self).before_execute()
return result and self.my_other_function()
这种方法唯一丢失的是能够重新排序链中各种功能的执行。您获得的是各种功能具有不同签名的能力(因为您明确地调用它们)。此外,这种范式似乎更典型/预期,这将导致更高的可读性(恕我直言)。
答案 1 :(得分:1)
你可以这样做:
#!/usr/bin/python
run_before = []
def append_to_before_fns(func):
global run_before
run_before.append(func)
@append_to_before_fns
def hello():
print 'hello '
@append_to_before_fns
def world():
print 'world'
def run():
global run_before
for f in run_before:
f()
if __name__=='__main__':
run()
会输出
hello
world
在Executor类中声明装饰器,然后可以在子类中调用它。