Intelligently Execute Python Functions in Order
我很好奇在程序中调用函数的相对优点是什么,使用一个修饰器来创建函数的有序映射,并遍历该映射,而不是直接按我想要的顺序调用函数。下面是两个产生相同结果的示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | 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() |
印刷品:
1 2 3 | first function middle function last function |
这是否比执行以下操作更好?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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进行拓扑排序,以获得节点的线性数组。
我说的是第二种方法,除非您不知何故想调用很多函数,而且太懒惰而无法键入(如果您确实这样做了,那么您的结构可能有问题)。它不仅可读性更强,从而有助于最小化不必要的错误,而且还更短。