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

举报
未闻Code 发表于 2022/01/23 15:00:42 2022/01/23
【摘要】 今天在 Github 阅读EdgeDB的代码,发现它在处理大量if...elif...else判断的时候,使用了一个非常巧妙的装饰器。

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

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

def get_discount(level):
    if level == 1:
        "大量计算代码"
        discount = 0.1
    elif level == 2:
        "大量计算代码"
        discount = 0.2
    elif level == 3:
        discount = 0.3
    elif level == 4:
        discount = 0.4
    elif level == 5:
        discount = 0.5
    elif level == 6:
        discount = 3 + 2 - 5 * 0.1
    else:
         return '等级错误'
    return discount

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

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

def parse_level_1():
    "大量计算代码"
    discount = 0.1
    return discount

def parse_level_2():
    "大量计算代码"
    discount = 0.2
    return discount

def parse_level_3():
    "大量计算代码"
    discount = 0.3
    return discount

def parse_level_4():
    "大量计算代码"
    discount = 0.4
    return discount

def parse_level_5():
    "大量计算代码"
    discount = 0.5
    return discount

def parse_level_6():
    "大量计算代码"
    discount = 3 + 2 - 5 * 0.1
    return discount

discount_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, '等级错误')

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

@value_dispatch
def get_discount(level):
    return '等级错误'

@get_discount.register(1)
def parse_level_1(level):
    "大量计算代码"
    discount = 0.1
    return discount

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

@get_discount.register(3)
def parse_level_3(level):
    "大量计算代码"
    discount = 0.3
    return discount

@get_discount.register(4)
def parse_level_4(level):
    "大量计算代码"
    discount = 0.4
    return discount

@get_discount.register(5)
def parse_level_5(level):
    "大量计算代码"
    discount = 0.5
    return discount

@get_discount.register(6)
def parse_level_1(level):
    "大量计算代码"
    discount = 3 + 2 - 5 * 0.1
    return discount


discount = get_discount(3)
print(f'等级3的用户,获得的折扣是:{discount}')

运行效果如下图所示:

12.png

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

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

13.png

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

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

运行效果如下图所示:

14.png

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

参考文献

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

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

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。