我有5组请求的类别定义为python dicts,例如:
category1 = {'type1', 'type2', 'type3'}
category2 = {'type4', 'type5'}
category3 = {'type6', 'type7', 'type8', 'type9'}
category4 = {'type10', 'type11'}
category5 = {'type12', 'type13', 'type14'}
我需要使用他们的类别来处理请求,例如:
if request_type in category1:
# process category1 request
process_category1_request(...)
elif request_type in category2:
# process category2 request
process_category2_request(...)
elif...
我需要使用请求类型将请求分派给不同的函数来处理它。
我已经知道有些方法可以在Python中调度这些请求而无需使用if-elif,但我的问题是:在保持代码干净简单的同时,最好的方法是什么?
答案 0 :(得分:15)
如果request_type
可以出现在多个类别中,您可以使用元组按优先级顺序循环显示它们:
categories = (
(category1, dispatch1method),
(category2, dispatch2method),
(category3, dispatch3method),
(category4, dispatch4method),
(category5, dispatch5method),
)
next(method for cat, method in categories if request_type in cat)(arguments)
否则使用dict()
将类别类型映射到调度方法;重用上面相同的元组映射来构建调度:
category_dispatch = {}
for cat, dispatch in categories:
category_dispatch.update(dict.fromkeys(cat.keys(), dispatch))
然后只需在其上查找请求类型:
category_dispatch[request_type](arguments)
这样的映射查找比通过元组的扫描更快,我们必须依次测试每个类别,直到找到匹配为止。
事实上,可以通过颠倒相同的元组结构来维持优先级排序:
category_dispatch = {}
for cat, dispatch in reversed(categories):
category_dispatch.update(dict.fromkeys(cat.keys(), dispatch))
因为现在给定request_type
密钥的最高优先级映射将最后输入category_dispatch
结构。即使请求类型存在于多个类别中,这也将为您提供最快的发送。
缺点是,如果您的category*
映射是动态的(随着时间的推移,请求类型会被添加到不同类别或从中删除),您需要维护category_dispatch
dict以反映这些更改。< / p>
答案 1 :(得分:4)
我认为最干净的可能是两张地图,以使代码最具可读性。
type_category_map = {"type1" : "category1",
"type2" : "category1", ,
"type3" : "category1",
"type4" : "category2",
....
"type14" : "category5"}
category_function_map = {"category1" : "handler1_function",
"category2" : "handler2_function,
....
}
然后python就是这样:
category = type_category_map[request_type]
handler_function = category_function_map[category]
handler_function(request)
我认为,有一种方法可以用单一数据结构来实现,但没有一种方法可以像我这样清楚易懂。
答案 2 :(得分:3)
将您的类别映射到处理程序。与您将拥有的地图大小无关 O(1)访问时间。
MAP = {
'cat1': handler1,
'cat2': handler2,
....
}
MAP[request_type](...)
答案 3 :(得分:3)
您不能指定像
这样的字典category1 = {'type1','type2','type3'}
你这里没有键值。
关于你的问题,这是一个对你有利的简单解决方案吗?
dispatchers = {}
def register_dispatches(types, dispatcher):
dispatchers.update(dict.fromkeys(types, dispatcher))
def process(request_type, *args, **kwargs):
dispatchers[request_type](*args, **kwargs)
register_dispatches(['type1', 'type2', 'type3'], process_category1_request)
register_dispatches(['type4', 'type5'], process_category2_request)
...
process(request_type, ...)
答案 4 :(得分:2)
categories = {request1 : dispatch1, request2 : dispatch2, request3 : dispatch3}
for category, dispatch in categories.iteritems():
if something in category:
dispatch(something)
这个怎么样?