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

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

今天在 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}')


运行效果如下图所示:


1.png


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


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


2.png


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


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


运行效果如下图所示:


3.png


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


参考文献


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


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


请关注微信公众号【未闻Code】获取更多精彩文章。

目录
相关文章
|
11月前
|
数据可视化 数据挖掘 Python
Pandas数据探索性可视化的最佳实践
【10月更文挑战第13天】数据可视化是数据分析中不可或缺的一环,它帮助我们更好地理解数据、发现趋势和模式,并有效地传达我们的发现。在Python领域,Pandas和Matplotlib是两个非常强大的库,它们提供了丰富的功能来进行数据分析和可视化。本文将介绍如何结合使用Pandas和Matplotlib进行数据探索性可视化的最佳实践。
|
机器学习/深度学习 自然语言处理 算法
2024年4月计算机视觉论文推荐
四月的计算机视觉研究涵盖多个子领域,包括扩散模型和视觉语言模型。在扩散模型中,Tango 2通过直接偏好优化改进了文本到音频生成,而Ctrl-Adapter提出了一种有效且通用的框架,用于在图像和视频扩散模型中添加多样控制。视觉语言模型的论文分析了CLIP模型在有限资源下的优化,并探讨了语言引导对低级视觉任务的鲁棒性。图像生成与编辑领域关注3D感知和高质量图像编辑,而视频理解与生成则涉及实时视频转游戏环境和文本引导的剪贴画动画。
283 0
|
TensorFlow 算法框架/工具
运行tensorboard报错:ValueError: Duplicate plugins for name projector
运行tensorboard报错:ValueError: Duplicate plugins for name projector
611 0
|
机器学习/深度学习 文字识别 算法
[Halcon&图像] 基于多层神经网络MLP分类器的思想提取颜色区域
[Halcon&图像] 基于多层神经网络MLP分类器的思想提取颜色区域
388 0
|
Ubuntu Java Linux
Java演进问题之Java 16对元空间优化如何解决
Java演进问题之Java 16对元空间优化如何解决
113 0
|
数据采集 数据处理 Python
Python爬虫程序中的504错误:原因、常见场景和解决方法
Python爬虫程序中的504错误:原因、常见场景和解决方法
|
存储 JSON 前端开发
JSON格式转换工具:快速、简单、高效处理JSON数据
JSON格式转换工具:快速、简单、高效处理JSON数据
976 1
|
应用服务中间件 Linux nginx
百度搜索:蓝易云【Docker容器安装Nginx教程。】
注意:在运行容器时,可以根据需要使用其他参数进行自定义配置,例如将本地文件挂载到容器中,或者使用自定义配置文件等。这些配置超出了本教程的范围,但你可以参考Docker文档和Nginx文档以获取更多详细信息。
249 2
|
算法
实现人脸美白算法---OpenCV-Python开发指南(59)
实现人脸美白算法---OpenCV-Python开发指南(59)
984 0
实现人脸美白算法---OpenCV-Python开发指南(59)
|
SQL 关系型数据库 MySQL
Could not execute query ---> MySql.Data.MySqlClient.MySqlException: You have an error in your SQL sy
Could not execute query ---> MySql.Data.MySqlClient.MySqlException: You have an error in your SQL sy
105 0