我很好奇在程序中调用函数的相对优点是什么,使用一个修饰器来创建函数的有序映射,并遍历该映射,而不是直接按我想要的顺序调用函数。下面是两个产生相同结果的示例:

PROCESS_MAP = {}
def register(call_order):
def decorator(process_func):
PROCESS_MAP[call_order] = process_func
return process_func
return decorator
@register(99)
def func3():
print 'last function'
@register(1)
def func0():
print 'first function'
@register(50)
def func1():
print 'middle function'
def main():
for func in sorted(PROCESS_MAP):
foo = PROCESS_MAP[func]
foo()
if __name__ == '__main__':
main()
印刷品:
first function
middle function
last function
这是否比执行以下操作更好?
def func2():
print 'last function'
def func0():
print 'first function'
def func1():
print 'middle function'
def main():
func0()
func1()
func2()
if __name__ == '__main__':
main()

还有一些问题:

更多的Python?

比它的价值更多的工作?

如果您没有正确分配订单,它是否会打开太多问题的大门?

是否有更智能的设计来按正确的顺序调用函数?

这是一个相当聪明的使用装饰器的方法,但我认为它使您的程序逻辑更难遵循。

如果函数必须始终以相同的顺序调用在一起,则表明它们的行为类似于一个长函数。

在我能想到的所有情况下,我更喜欢第二种(非装饰)方法。显式地命名函数是直接的、明显的和清晰的。考虑问"这个函数是从哪里调用的?"以及在每种情况下你如何回答这个问题。

在您的装饰器中有一个可能的bug,它会悄悄地删除一个与另一个函数具有相同调用顺序号的函数。

如果您希望根据参数调整函数顺序,或者如果您经常更改顺序并希望使用脚本,那么第一个脚本确实会给您带来优势。

第一个可以让您在需要时动态地更改顺序,还可以让您使用外部脚本更容易地更改顺序。

如果你的程序逻辑清晰而简单,或者如果你的程序有一天会变得更复杂,并且装饰器会变得不相关/需要进行重大的修改以适应-使用第二个。

您可以在这里了解更多常用的装饰:Python装饰器的一些常见用途是什么?

但最后,我想说,这真的取决于你的设计和程序的目的。此外,我建议,如果选择第一种方法,写一个更好的机制来记录顺序,处理两个函数等等。这些改进可能会使装饰师值得。

Peak Rules有一些有趣的实用程序,包括@before,@after decorators和一个有趣的系统,用于制定规则来强制执行某些行为。

一个更简单的机制是为每个函数分配一个"权重",然后按加权顺序对它们进行排序——尽管这假定一个函数数组。如果存在层次结构,可以对DAG进行拓扑排序,以获得节点的线性数组。

我说的是第二种方法,除非您不知何故想调用很多函数,而且太懒惰而无法键入(如果您确实这样做了,那么您的结构可能有问题)。它不仅可读性更强,从而有助于最小化不必要的错误,而且还更短。