服务器之家

服务器之家 > 正文

一日一技:使用装饰器简化大量 if…elif…代码

时间:2021-11-12 22:30     来源/作者:未闻Code

一日一技:使用装饰器简化大量 if…elif…代码

今天在 Github 阅读EdgeDB[1]的代码,发现它在处理大量if...elif...else判断的时候,使用了一个非常巧妙的装饰器。我们来看看这个方法具体是什么样的。

正好今天是双十一,假设我们要做一个功能,根据用户的等级判断他可以获得的折扣。常规的if ... elif...写法是这样的:

  1. def get_discount(level):
  2. if level == 1:
  3. "大量计算代码"
  4. discount = 0.1
  5. elif level == 2:
  6. "大量计算代码"
  7. discount = 0.2
  8. elif level == 3:
  9. discount = 0.3
  10. elif level == 4:
  11. discount = 0.4
  12. elif level == 5:
  13. discount = 0.5
  14. elif level == 6:
  15. discount = 3 + 2 - 5 * 0.1
  16. else:
  17. return '等级错误'
  18. return discount

大家都知道,这样大量的if ... elif...代码非常难看,也很难维护。并且每个 if 的内部有很多代码。这个函数就会被拉得非常长。

有一些同学知道,可以使用字典来改写这个太长的 if 判断:

  1. def parse_level_1():
  2. "大量计算代码"
  3. discount = 0.1
  4. return discount
  5. def parse_level_2():
  6. "大量计算代码"
  7. discount = 0.2
  8. return discount
  9. def parse_level_3():
  10. "大量计算代码"
  11. discount = 0.3
  12. return discount
  13. def parse_level_4():
  14. "大量计算代码"
  15. discount = 0.4
  16. return discount
  17. def parse_level_5():
  18. "大量计算代码"
  19. discount = 0.5
  20. return discount
  21. def parse_level_6():
  22. "大量计算代码"
  23. discount = 3 + 2 - 5 * 0.1
  24. return discount
  25. discount_map = {
  26. 1: parse_level_1,
  27. 2: parse_level_2,
  28. 3: parse_level_3,
  29. 4: parse_level_4,
  30. 5: parse_level_5,
  31. 6: parse_level_6,
  32. }
  33. discount = discount_map.get(level, '等级错误')

但今天我学到的这个方法,比用字典更简单。我们先来看它的效果:

  1. @value_dispatch
  2. def get_discount(level):
  3. return '等级错误'
  4. @get_discount.register(1)
  5. def parse_level_1(level):
  6. "大量计算代码"
  7. discount = 0.1
  8. return discount
  9. @get_discount.register(2)
  10. def parse_level_2(level):
  11. "大量计算代码"
  12. discount = 0.2
  13. return discount
  14. @get_discount.register(3)
  15. def parse_level_3(level):
  16. "大量计算代码"
  17. discount = 0.3
  18. return discount
  19. @get_discount.register(4)
  20. def parse_level_4(level):
  21. "大量计算代码"
  22. discount = 0.4
  23. return discount
  24. @get_discount.register(5)
  25. def parse_level_5(level):
  26. "大量计算代码"
  27. discount = 0.5
  28. return discount
  29. @get_discount.register(6)
  30. def parse_level_1(level):
  31. "大量计算代码"
  32. discount = 3 + 2 - 5 * 0.1
  33. return discount
  34. discount = get_discount(3)
  35. print(f'等级3的用户,获得的折扣是:{discount}')

一日一技:使用装饰器简化大量 if…elif…代码

这样写,比用字典的方式更直观,比直接用if ... elif...更简洁。

那么,这个装饰器value_dispatch是怎么实现的呢?密码就藏在这个开源项目EdgeDB的源代码[2]中,核心代码只有20多行:

一日一技:使用装饰器简化大量 if…elif…代码

并且,还能够实现或查询。例如用户等级为2或者3的时候,折扣都是0.2,那么代码可以写成:

  1. @get_discount.register(2)
  2. @get_discount.register(3)
  3. def parse_level_2(level):
  4. "大量计算代码"
  5. discount = 0.2
  6. return discount

运行效果如下图所示:

一日一技:使用装饰器简化大量 if…elif…代码

它这个代码目前只能实现相等的查询。但其实只要对这个代码稍作修改,我们就能实现大于、小于、大于等于、小于等于、不等于、in等等判断。如果大家有兴趣的话,请在文章下面留言,我们明天就来说说怎么对这个代码进行改造,实现更多的逻辑判断。

参考文献

[1] EdgeDB: https://github.com/edgedb/edgedb

[2] 源代码: https://github.com/edgedb/edgedb/blob/master/edb/common/value_dispatch.py

原文链接:https://mp.weixin.qq.com/s/eGji_6PBkf-vK2SQPB0WTQ

标签:

相关文章

热门资讯

yue是什么意思 网络流行语yue了是什么梗
yue是什么意思 网络流行语yue了是什么梗 2020-10-11
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
背刺什么意思 网络词语背刺是什么梗
背刺什么意思 网络词语背刺是什么梗 2020-05-22
2021年耽改剧名单 2021要播出的59部耽改剧列表
2021年耽改剧名单 2021要播出的59部耽改剧列表 2021-03-05
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总 2020-11-13
返回顶部