当前位置: 首页 > 科技观察

每日一技能:用装饰器简化大量if...elif...代码

时间:2023-03-21 12:28:40 科技观察

今天在Github上看了EdgeDB[1]的代码,发现里面大量使用了if...elif...else判断非常聪明的装饰器。让我们来看看这个方法是什么样子的。恰好今天是双十一。假设我们要创建一个函数,根据用户的等级来判断用户可以获得的折扣。常规的if...elif...是这样写的:defget_discount(level):iflevel==1:"大量计算代码"discount=0.1eliflevel==2:"大量计算代码"discount=0.2eliflevel==3:discount=0.3eliflevel==4:discount=0.4eliflevel==5:discount=0.5eliflevel==6:discount=3+2-5*0.1else:return'levelerror'returndiscount大家都知道,如此大量的if...elif...代码丑陋且难以维护。如果有很多代码,则在每个内部。这个函数会被拉得很长。有同学知道可以用字典重写这个太长if判断:defparse_level_1():"大量计算代码"discount=0.1returndiscountdefparse_level_2():"大量计算代码"discount=0.2returndiscountdefparse_level_3():"大量计算代码"discount=0.3returndiscountdefparse_level_4():"大量计算代码"discount=0.4returndiscountdefparse_level_5():"大量计算代码"discount=0.5returndiscountdefparse_level_6():"大量计算代码"discount=3+2-5*0.1returndiscountdiscount_map={1:parse_level_1,2:parse_level_2,3:parse_level_3,4:parse_level_4,5:parse_level_5,6:parse_level_6,}discount=discount_map.get(level,'levelerror')不过我今天学到的方法比用字典简单多了。先看它的效果:@value_dispatchdefget_discount(level):return'levelerror'@get_discount.register(1)defparse_level_1(level):"大量计算代码"discount=0.1returndiscount@get_discount.register(2)defparse_level_2(level):"大量计算代码"discount=0.2returndiscount@get_discount.register(3)defparse_level_3(level):"大量计算代码"discount=0.3returndiscount@get_discount.register(4)defparse_level_4(level):"大量计算代码"discount=0.4returndiscount@get_discount.register(5)defparse_level_5(level):"大量计算代码"discount=0.5returndiscount@get_discount.register(6)defparse_level_1(level):"大量计算码"discount=3+2-5*0.1returndiscountdiscount=get_discount(3)print(f'3级用户,得到的折扣为:{discount}')这样写比用更直观一个字典,而且比直接使用if...elif...更简洁。那么,这个dec怎么样oratorvalue_dispatch实现了吗?密码隐藏在开源项目EdgeDB的源代码[2]中,核心代码只有20多行:而且还可以实现或查询。比如当用户等级为2或3时,折扣为0.2,那么代码可以写成:@get_discount.register(2)@get_discount.register(3)defparse_level_2(level):"大计算代码"折扣=0.2returndiscount运行效果如下图:这段代码目前只能实现相等查询。但其实只要稍加修改这段代码,我们就可以实现大于、小于、大于等于、小于等于、不等于、in等判断。如果您有兴趣,请在文章下方留言。明天我们再说如何修改这段代码,实现更多的逻辑判断。参考资料[1]EdgeDB:https://github.com/edgedb/edgedb[2]源码:https://github.com/edgedb/edgedb/blob/master/edb/common/value_dispatch.py