调度请求时,if-elif-elif-elif的Python最佳实践

Ser*_*rán 7 python if-statement switch-statement dispatch

我有5组请求的类别定义为python dicts,例如:

category1 = {'type1', 'type2', 'type3'}
category2 = {'type4', 'type5'}
category3 = {'type6', 'type7', 'type8', 'type9'}
category4 = {'type10', 'type11'}
category5 = {'type12', 'type13', 'type14'}
Run Code Online (Sandbox Code Playgroud)

我需要使用他们的类别来处理请求,例如:

if request_type in category1:
    # process category1 request
    process_category1_request(...)
elif request_type in category2:
    # process category2 request
    process_category2_request(...)
elif...
Run Code Online (Sandbox Code Playgroud)

我需要使用请求类型将请求分派给不同的函数来处理它.

我已经知道有些方法可以在Python中调度这些请求而无需使用if-elif,但我的问题是:在保持代码干净简单的同时,最好的方法是什么?

Mar*_*ers 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)
Run Code Online (Sandbox Code Playgroud)

否则使用a dict()来映射类别类型来代替调度方法; 重用上面相同的元组映射来构建调度:

category_dispatch = {}
for cat, dispatch in categories:
    category_dispatch.update(dict.fromkeys(cat.keys(), dispatch))
Run Code Online (Sandbox Code Playgroud)

然后只需在上面查找请求类型:

category_dispatch[request_type](arguments)
Run Code Online (Sandbox Code Playgroud)

像这样的映射查找比通过元组的扫描更快,在那里我们必须依次测试每个类别,直到我们找到匹配.

实际上,可以通过反转相同的元组结构来维持优先级排序,如下所示:

category_dispatch = {}
for cat, dispatch in reversed(categories):
    category_dispatch.update(dict.fromkeys(cat.keys(), dispatch))
Run Code Online (Sandbox Code Playgroud)

从现在起,给定request_type密钥的最高优先级映射将category_dispatch最后输入到结构中.即使请求类型存在于多个类别中,这也将为您提供最快的调度.

缺点是如果您的category*映射是动态的(随着时间的推移,请求类型会被添加到不同的类别中或从中删除),您还需要维护category_dispatchdict以反映这些更改.

  • 不是我,我认为你的答案是(像往常一样)踢屁股 (3认同)