优美胜于丑陋
import this
前言
表驱动法是一种编辑模式(Scheme)——从表里面查找信息而不使用逻辑语句(if 和 case)。事实上,凡是能通过逻辑语句来选择的事物,都可以通过查表来选择。
对简单的情况而言,使用逻辑语句更为容易和直白。但随着逻辑链的越来越复杂,查表法也就愈发显得更具吸引力。
Python的switch case
由于Python中没有switch case关键词,所以对于每一种情况的逻辑语句只能用if
,elif
,else
来实现。
1 | def handle_case(case): |
而当条件变得很多和各个条件的内部处理逻辑背景复杂时,整个代码块就会变得很臃肿。本文将讨论两种方案,来处理这种情况。
显式Dict实现
使用dict来索引各个case的处理函数,并在主入口统一处理。
1 |
|
装饰器实现
而受到PEP-443: Single-dispatch generic functions的启发,很容易就能实现如下装饰器:
1 | from functools import update_wrapper |
而之前的代码就能很简洁的重构成这样:
1 |
|
而对于这样的架构,即易于扩展也利于维护。
更多实例
1 | class Test: |
总结
对比两种处理方案,区别在于显式dict的存在。对于显式的dict存在,方便索引和查看具体case和对应的处理函数,而对于case的增加或者删除,都得增加或删除对应主入口中case和func的键值对。而装饰器的存在简化了上述步骤,而对应的代价则是将dict的存在隐式化了,类似的设计模式同Web框架中路由注册。
- specificdispatch只是一个单纯的functool,import了就能用的那种,从行数上来说,使用装饰器和字典来说基本是没有差别的。
- 从性能角度来说,查表的方法(字典和装饰器)的性能都是是比
if
elif
要高的,是O(1)的性能。 - 字典和装饰器的方法,唯一的区别也是在字典是否显式存在,以及是否需要手动维护。