Python项目代码太多if-else? 这样优化才优雅!

前言

代码中不可避免地会出现复杂的if-else条件逻辑,而简化这些条件表达式是一种提高代码可读性极为实用的技巧。

在 Python 中,有多种方法可以避免复杂的 if-else 条件逻辑,使代码更加清晰和易于维护。

筑基期

提前 return,去掉多余的 else

在 Python 中,使用"提前返回"(early return)可以避免深层嵌套的if-else语句,并且使代码更加清晰。

场景:电商平台为首次购买的用户在结账时提供优惠券。如果用户不是首次购买,或者购物车中的商品总额低于某个阈值,则不提供优惠券。

未使用提前返回的原始代码

def apply_coupon(user, cart):
    if user.is_first_purchase:
        if cart.total_amount >= 100:
            cart.apply_discount(10)  # 应用10%的折扣
            print("A coupon has been applied to your purchase.")
        else:
            print("Your purchase does not meet the minimum amount for a coupon.")
    else:
        print("Coupons are only available for first-time purchases.")
    return cart

使用提前返回优化后的代码

def apply_coupon(user, cart):
    # 检查是否为首次购买
    if not user.is_first_purchase:
        print("Coupons are only available for first-time purchases.")
        return cart

    # 检查购物车总额是否满足条件
    if cart.total_amount < 100:
        print("Your purchase does not meet the minimum amount for a coupon.")
        return cart

    # 应用优惠券
    cart.apply_discount(10)  # 应用10%的折扣
    print("A coupon has been applied to your purchase.")
    return cart

首先,定义用户和购物车类,以及必要的属性和方法:

class User:
    def __init__(self, is_first_purchase):
        self.is_first_purchase = is_first_purchase

class Cart:
    def __init__(self, total_amount):
        self.total_amount = total_amount
        self.discount = 0

    def apply_discount(self, percentage):
        self.discount = self.total_amount * (percentage / 100)
        self.total_amount -= self.discount

    def __str__(self):
        return f"Cart(total_amount={
     self.total_amount}, discount={
     self.discount})"

然后,我们创建两个用户和两个购物车对象。

  • 第一个用户是首次购买,购物车总额为150,满足应用优惠券的条件,因此会看到优惠券被应用,并且购物车总额减少。
  • 第二个用户不是首次购买,购物车总额为50,不满足应用优惠券的条件,因此会看到相应的提示信息,购物车总额不变。
# 创建用户对象,假设是首次购买
user = User(is_first_purchase=True)

# 创建购物车对象,假设购物车总额为150
cart = Cart(total_amount=150)

# 打印原始购物车状态
print("原始购物车状态:", cart)

# 调用apply_coupon函数
cart = apply_coupon(user, cart)

# 打印应用优惠券后的购物车状态
print("应用优惠券后的购物车状态:", cart)

# 再次创建一个购物车对象,假设购物车总额为50,且用户不是首次购买
another_user = User(is_first_purchase=False)
another_cart = Cart(total_amount=50)

# 打印原始购物车状态
print("\n原始购物车状态:", another_cart)

# 调用apply_coupon函数
another_cart = apply_coupon(another_user, another_cart)

# 打印应用优惠券后的购物车状态(实际上不会应用优惠券)
print("应用优惠券后的购物车状态(实际上不会应用优惠券):", another_cart)

在这个优化后的版本中,我们使用了提前返回来简化逻辑流程:

  1. 首先检查用户是否为首次购买,如果不是,则立即返回,不再执行后续代码。
  2. 然后检查购物车总额是否满足优惠券的最低限额,如果不满足,同样立即返回。
  3. 只有当这两个条件都满足时,才应用优惠券并打印相应的消息。

提前返回的好处

  • 逻辑清晰:每个条件都被单独检查,并且不满足时立即返回,逻辑流程非常清晰。
  • 减少嵌套:避免了深层嵌套的if-else结构,使得代码更加扁平化。
  • 易于维护:当需要修改条件或者添加新的条件时,可以很容易地在函数开头添加新的检查。
  • 避免冗余:去掉了不必要的else语句,因为每个if语句都有明确的返回点。

通过这种方式,提前返回使得代码更加简洁、直观,并且易于理解和维护。

使用合适的逻辑运算符

Python开发中,逻辑运算符andorinbool()not等可以帮助我们简化条件判断,从而减少if语句的使用。以下是使用逻辑运算符优化if语句的一个电商例子。

场景:电商平台想要为特定条件下的用户提供优惠券。条件包括:

  • 用户必须是新用户(is_new 属性为 True)。
  • 用户的购物车中必须包含至少一种电子产品(category 属性为 "electronics")。
  • 用户的购物车总价必须超过一定金额(例如200元)。

未使用逻辑运算符的原始代码

from collections import namedtuple


def apply_coupon(_cart_items, _user):
    if _user.is_new:
        if any(item['category'] == 'electronics' for item in _cart_items):
            if sum(item['price'] * item['quantity'] for item in _cart_items) > 200:
                # 应用优惠券逻辑
                print("Coupon applied!")
            else:
                print("Cart total is less than 200.")
        else:
            print("No electronics in cart.")
    else:
        print("User is not new.")


# 示例用户和购物车
User = namedtuple('User', ["is_new"])
user = User(is_new=True)
cart_items = [
    {
   'name': 'Laptop', 'category': 'electronics', 'price': 150, 'quantity': 1},
    {
   'name': 'Book', 'category': 'books', 'price': 50, 'quantity': 2},
]

apply_coupon(cart_items, user)  # Coupon applied!

使用逻辑运算符优化后的代码

from collections import namedtuple


def apply_coupon(cart_items, user):
    # 使用逻辑运算符组合条件
    new_user = user.is_new
    has_electronics = any(item['category'] == 'electronics' for item in cart_items)
    cart_total = sum(item['price'] * item['quantity'] for item in cart_items) > 200

    # 如果所有条件都满足,则应用优惠券
    if new_user and has_electronics and cart_total:
        print("Coupon applied!")
    else:
        print("Coupon not applied.")


# 示例用户和购物车
User = namedtuple('User', ["is_new"])
user = User(is_new=True)
cart_items = [
    {
   'name': 'Laptop', 'category': 'electronics', 'price': 150, 'quantity': 1},
    {
   'name': 'Book', 'category': 'books', 'price': 50, 'quantity': 2},
]

apply_coupon(cart_items, user)  # Coupon applied!

在这个优化后的版本中,我们首先使用逻辑运算符来单独评估每个条件:

  • new_user 检查用户是否为新用户。
  • has_electronics 检查购物车中是否有电子产品。
  • cart_total 检查购物车总价是否超过 200 元。

然后,我们使用and运算符来确保所有条件都满足,只有当这个组合条件为真时,才应用优惠券。

使用逻辑运算符的好处包括:

  1. 代码简化:减少了嵌套的if语句,使代码更加简洁。
  2. 逻辑清晰:每个条件的评估清晰明了,易于理解和维护。
  3. 易于调整:如果需要修改条件或添加新条件,只需调整逻辑表达式即可。

通过这种方式,逻辑运算符帮助我们编写出更加Pythonic和易于维护的代码。

提炼条件判断逻辑

当条件判断变得过于复杂时,它不仅难以理解,还可能导致代码维护困难。将复杂的条件判断逻辑提炼成独立的函数是一种很好的实践,这样可以使代码更加清晰、可读性更高,并且易于维护。

假设我们有一个函数,根据用户的购物车中的商品种类和数量来决定是否提供折扣。原始的代码可能包含多个嵌套的if-else语句,如下所示:

def calculate_discount(_cart_items):
    discount = 0
    if 'electronics' in _cart_items:
        if len(_cart_items['electronics']) >= 3:
            discount += 10
        if 'laptop' in _cart_items['electronics']:
            discount += 5
    elif 'clothing' in _cart_items:
        if len(_cart_items['clothing']) >= 5:
            discount += 15
    # ... 更多条件
    return discount

这个函数的可读性很差,很难一眼看出它在做什么。我们可以将复杂的条件判断逻辑提炼成独立的函数,如下所示:

# 定义检查商品的函数
def has_bulk_electronic_items(_cart_items):
    return len(_cart_items.get('electronics', [])) >= 3


def has_laptop_in_electronics(_cart_items):
    return 'laptop' in _cart_items.get('electronics', [])


def has_many_clothing_items(_cart_items):
    return len(_cart_items.get('clothing', [])) >= 5


# 定义计算折扣的函数
def calculate_discount(_cart_items):
    discount = 0
    if has_bulk_electronic_items(_cart_items):
        discount += 10  # 电子产品数量超过3个,折扣10%
    if has_laptop_in_electronics(_cart_items):
        discount += 5  # 电子产品中有笔记本电脑,额外折扣5%
    if has_many_clothing_items(_cart_items):
        discount += 15  # 服装数量超过5个,折扣15%
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/679380.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++基础编程100题-003 OpenJudge-1.1-05 输出保留12位小数的浮点数

更多资源请关注纽扣编程微信公众号 http://noi.openjudge.cn/ch0101/05/ 描述 读入一个双精度浮点数&#xff0c;保留12位小数&#xff0c;输出这个浮点数。 输入 只有一行&#xff0c;一个双精度浮点数。 输出 也只有一行&#xff0c;保留12位小数的浮点数。 样例输入…

Day 42 LVS四层负载均衡

一&#xff1a;负载均衡简介 1.集群是什么 ​ 集群&#xff08;cluster&#xff09;技术是一种较新的技术&#xff0c;通过集群技术&#xff0c;可以在付出较低成本的情况下获得在性能、可靠性、灵活性方面的相对较高的收益&#xff0c;其任务调度则是集群系统中的核心技术 …

LangChain学习之 Question And Answer的操作

1. 学习背景 在LangChain for LLM应用程序开发中课程中&#xff0c;学习了LangChain框架扩展应用程序开发中语言模型的用例和功能的基本技能&#xff0c;遂做整理为后面的应用做准备。视频地址&#xff1a;基于LangChain的大语言模型应用开发构建和评估。 2. Q&A的作用 …

web刷题记录(2)

[鹤城杯 2021]EasyP 就是php的代码审计 从中可以看出来&#xff0c;就是对四个if语句的绕过&#xff0c;然后过滤了一些语句 代码分析&#xff1a; 通过include utils.php;导入了一个叫做"utils.php"的文件&#xff0c;这意味着在该文件中可能定义了一些与本代码相…

通信协议:常见的芯片间通信协议

相关阅读 通信协议https://blog.csdn.net/weixin_45791458/category_12452508.html?spm1001.2014.3001.5482 本文将简单介绍一些常见的芯片间通信协议&#xff0c;但不会涉及到协议的具体细节。首先说明&#xff0c;芯片间通信方式根据通信时钟的区别可以分为&#xff1a;异步…

计算机网络ppt和课后题总结(上)

试在下列条件下比较电路交换和分组交换。要传送的报文共 x(bit)。从源点到终点共经过 k 段链路&#xff0c;每段链路的传播时延为 d(s)&#xff0c;数据率为 b(b/s)。在电路交换时电路的建立时间为 s(s)。在分组交换时分组长度为 p(bit)&#xff0c;且各结点的排队等待时间可忽…

基于YOLOv7的口罩检测

目录 1. 作者介绍2. YOLOv7网络模型2.1 算法简介2.2 数据集介绍2.3 YOLO格式数据集制作 3. 代码实现3.1 分割数据集3.2 修改数据配置文件3.3 修改训练代码&#xff0c;进行训练3.4 修改测试代码&#xff0c;进行测试3.5 检测结果 1. 作者介绍 曹宇欢&#xff0c;女&#xff0c…

跨越国界, 纷享销客助力企业全球业务增长

出海&#xff0c;已不再是企业的“备胎”&#xff0c;而是必须面对的“大考”&#xff01;在这个全球化的大潮中&#xff0c;有的企业乘风破浪&#xff0c;勇攀高峰&#xff0c;也有的企业在异国他乡遭遇了“水土不服”。 面对“要么出海&#xff0c;要么出局”的抉择&#xff…

盲盒风尚:拆盒吧引领新潮消费趋势

在当下这个快速变化的消费时代&#xff0c;拆盒吧以其独特的盲盒经济模式&#xff0c;成为了新潮文化消费的引领者。不同于传统的购物方式&#xff0c;拆盒吧通过创新的玩法和多元化的产品线&#xff0c;为消费者带来了前所未有的购物体验。 一、拆盒吧&#xff1a;解锁盲盒新玩…

现代密码学-国密算法

商用密码算法种类 商用密码算法 密码学概念、协议与算法之间的依赖关系 数字签名、证书-公钥密码、散列类算法 消息验证码-对称密码 &#xff0c;散列类 安全目标与算法之间的关系 机密性--对称密码、公钥密码 完整性--散列类算法 可用性--散列类、公钥密码 真实性--公…

数据结构之初始泛型

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;数据结构&#xff08;Java版&#xff09; 目录 深入了解包装类 包装类的由来 装箱与拆箱 面试题 泛型 泛型的语法与使用…

可长期操作的赚钱项目,时间自由,但不适合大学生

如何评价现在的csgo市场&#xff1f; 可长期操作的赚钱项目&#xff0c;时间自由&#xff0c;但不适合大学生。 都在问&#xff0c;有哪些可以长期做下去的赚钱项目&#xff0c;童话就不拐弯抹角了&#xff0c;csgo/steam游戏搬砖一定是最适合长期做下去的赚钱项目。 不说别人…

CondaSSLError: OpenSSL appears to be unavailable on this machine.

conda create -n x1 python3.7报错 PS C:\Users\Richardo.M.Song\Desktop\lele_seg\x1> conda create -n x1 python3.7 Collecting package metadata (current_repodata.json): failed CondaSSLError: OpenSSL appears to be unavailable on this machine. OpenSSL is requ…

Varnish讲解文章、缓存代理配置、核心功能、优势、Varnish在什么情况下会选择缓存哪些类型的内容、Varnish如何实现负载均衡功能?

varnish官网链接 Varnish文章概览 Varnish是一款高性能的HTTP加速器&#xff08;web应用加速器&#xff09;&#xff0c;是一款开源软件&#xff0c;它能够显著提高网站的响应速度和减少服务器的负载。Varnish的设计理念是利用缓存技术&#xff0c;将频繁访问的静态内容存储在…

【Python】 探索Pytz库中的时区列表

基本原理 在Python中&#xff0c;处理时区是一个常见但复杂的问题。pytz是一个Python库&#xff0c;它提供了对时区的精确和丰富的支持。pytz库是datetime模块的补充&#xff0c;它允许更准确地处理时区信息。pytz库包括了IANA时区数据库&#xff0c;这个数据库包含了全球的时…

13-至少有5名直接下属的经理(高频 SQL 50 题基础版)

13-至少有5名直接下属的经理 select name from Employee where id in (select managerId -- 查找大于5的经理idfrom Employeegroup by managerId -- 根据id分组having count(*)>5); -- 根据分组的数据进行求个数

小白级教程—安装Ubuntu 20.04 LTS服务器

下载 本教程将使用20.04版进行教学 由于官方速度可能有点慢&#xff0c;可以下方的使用清华镜像下载 https://mirrors.tuna.tsinghua.edu.cn/ubuntu-releases/ 点击20.24版本 选择 ubuntu-20.04.6-live-server-amd64.iso 新建虚拟机 下载好后 我们使用 VMware 打开它 这里选…

使用Python和wxPython将PNG文件转换为JPEG文件

简介&#xff1a; 在图像处理中&#xff0c;有时候我们需要将PNG格式的图像文件转换为JPEG格式。本篇博客将介绍如何使用Python编程语言和wxPython图形用户界面库&#xff0c;以及Pillow图像处理库来实现这一转换过程。通过本文的指导&#xff0c;您将学习如何快速将指定文件夹…

Docker run 命令常用参数详解

Docker run 命令提供了丰富的参数选项&#xff0c;用于配置容器的各种设置。以下是docker run命令的主要参数详解&#xff0c; 主要参数详解 后台运行与前台交互 -d, --detach: 在后台运行容器&#xff0c;并返回容器ID。-it: 分配一个伪终端&#xff08;pseudo-TTY&#xff0…

路由策略案例

一、路由策略案例 如图所示&#xff0c;某公司内终端通过Switch接入公司内部网络。如果该公司内存在非如图1所示&#xff0c;运行OSPF协议的网络中&#xff0c;RouterA从Internet网络接收路由&#xff0c;并头RouterB提供了部分Internet路由。其中: RouterA仅提供172.1…