优雅的避免代码嵌套 (表驱动 | 状态模式 | lambda | 编程 | 断言和前置判断 | 设计模式)

1. 表驱动法(Table-Driven Approach)

使用数据结构来存储逻辑关系,通过查表的方式避免代码的嵌套。这种方法适用于一些规则比较固定的场景,例如状态机、字符转换等。

  • 定义一个数据结构,如数组、哈希表或配置文件,用于存储逻辑关系。
  • 将原本嵌套的逻辑转化为通过查表来获取结果的方式。
  • 通过修改表的内容,可以实现逻辑的动态调整,而无需修改源代码。

假设我们有一个函数根据不同的颜色返回对应的 RGB 值,可以使用表驱动法来避免嵌套的 if-else 语句:

color_mappings = {'red': (255, 0, 0),'green': (0, 255, 0),'blue': (0, 0, 255)
}def get_rgb(color):return color_mappings.get(color, (0, 0, 0))

2. 状态模式(State Pattern)

将复杂的状态逻辑封装在对象中,通过状态切换来控制程序流程,避免了嵌套的 if-else 语句。这种方法适用于需要处理多个状态的场景,例如游戏中的角色状态、订单状态等。

  • 将各种状态封装成独立的类,并定义共同的接口。
  • 每个状态类负责自身的行为和状态转换。
  • 在主程序中切换状态,使得代码逻辑更加清晰,避免复杂的嵌套条件语句。

假设我们有一个状态机,根据不同的状态执行不同的操作,可以使用状态模式来避免嵌套的条件语句:

class State:def handle(self):passclass StateA(State):def handle(self):print("State A")class StateB(State):def handle(self):print("State B")class Context:def __init__(self):self.state = Nonedef set_state(self, state):self.state = statedef handle(self):self.state.handle()# 使用示例:
context = Context()
context.set_state(StateA())
context.handle()  # 输出:State Acontext.set_state(StateB())
context.handle()  # 输出:State B

3. 使用 Lambda 表达式

使用 Lambda 表达式可以简化代码,使得代码更加易读,减少嵌套层数。Lambda 表达式适用于需要对集合进行操作的场景,例如筛选、排序、映射等。

  • 使用 Lambda 表达式可以将函数作为参数传递,简化代码结构。
  • 在集合操作中,可以使用 Lambda 表达式进行筛选、排序、映射等操作,减少临时变量和嵌套的循环语句。
  • Lambda 表达式可以提高代码的可读性和简洁性。

假设我们有一个列表,需要过滤出其中的偶数并进行加倍操作,可以使用 Lambda 表达式来避免嵌套的函数调用:

numbers = [1, 2, 3, 4, 5, 6]filtered_numbers = list(filter(lambda x: x % 2 == 0, numbers))
doubled_numbers = list(map(lambda x: x * 2, filtered_numbers))print(doubled_numbers)  # 输出:[4, 8, 12]

4. 断言和前置判断

在编写代码时,应该注意空值的情况,使用条件语句和异常处理来避免空指针异常,实现早返回和早退出(异常剪枝)。这种方法可以减少嵌套,使得代码更加健壮。

  • 在编写代码时,应该注意空值的情况,使用条件语句和异常处理来避免空指针异常。
  • 可以使用条件判断语句(如 if-else)或者空值合并操作符来进行空值判断,提前处理可能的空值情况。
  • 合理地使用断言、预检查和异常捕获机制,确保代码的健壮性。

假设我们有一个函数,对传入的字符串进行处理,如果为空则返回默认值,可以使用断言和前置条件来进行空值判断:

def process_string(data):assert data is not None, "数据不能为空"if not data:return "默认值"# 其他处理逻辑

5. 设计模式

使用设计模式可以将复杂的逻辑抽象成简单的模块,从而避免嵌套的 if-else 语句。例如工厂模式、观察者模式、装饰器模式等,都可以帮助我们编写更加优雅的代码。

  • 设计模式是一套被广泛接受的解决特定问题的经验总结,可以帮助我们避免代码嵌套。
  • 例如工厂模式将对象的创建和使用分离,减少了创建对象时的嵌套关系。
  • 观察者模式通过事件的订阅和发布,避免了多层的回调嵌套。
  • 装饰器模式可以动态地添加功能,而无需修改原有代码,避免了复杂的嵌套条件语句。

假设我们有一个订单系统,需要根据不同的支付方式执行不同的支付策略,可以使用策略模式来避免嵌套的条件语句:

class PaymentStrategy:def pay(self):passclass AlipayStrategy(PaymentStrategy):def pay(self):print("支付宝支付")class WechatPayStrategy(PaymentStrategy):def pay(self):print("微信支付")class PaymentContext:def __init__(self, strategy):self.strategy = strategydef execute_payment(self):self.strategy.pay()# 使用示例:
payment_alipay = PaymentContext(AlipayStrategy())
payment_alipay.execute_payment()  # 输出:支付宝支付payment_wechat = PaymentContext(WechatPayStrategy())
payment_wechat.execute_payment()  # 输出:微信支付

6. 高阶函数

在 Python 中,高阶函数是指能够接受其他函数作为参数或返回函数作为结果的函数。筛选filter、排序sort、分组group、投影map是几个常用的高阶函数示例:

  1. 筛选(filter):

    • filter() 函数可以根据指定的条件过滤可迭代对象中的元素。
    • 语法:filter(function, iterable)
    • 示例:
      numbers = [1, 2, 3, 4, 5, 6]
      even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
      print(even_numbers)  # 输出 [2, 4, 6]
      
  2. 排序(sort):

    • sort() 函数可以对可迭代对象进行排序,可以指定自定义的比较函数。
    • 语法:sorted(iterable, key=..., reverse=...)list.sort(key=..., reverse=...)
    • 示例:
      numbers = [5, 2, 8, 1, 6]
      sorted_numbers = sorted(numbers)
      print(sorted_numbers)  # 输出 [1, 2, 5, 6, 8]names = ["Alice", "Bob", "Charlie", "David"]
      sorted_names = sorted(names, key=lambda x: len(x))
      print(sorted_names)  # 输出 ["Bob", "Alice", "David", "Charlie"]
      
  3. 分组(group):

    • groupby() 函数可以根据指定的键对可迭代对象进行分组。
    • 需要先对可迭代对象进行排序,然后再使用 groupby() 函数。
    • 语法:itertools.groupby(iterable, key=...)
    • 示例:
      from itertools import groupbynumbers = [1, 1, 2, 3, 3, 3, 4, 5, 5]
      grouped_numbers = groupby(numbers)
      for key, group in grouped_numbers:print(key, list(group))
      # 输出
      # 1 [1, 1]
      # 2 [2]
      # 3 [3, 3, 3]
      # 4 [4]
      # 5 [5, 5]
      
  4. 投影(map):

    • map() 函数可以将指定的函数应用于可迭代对象的每个元素,并返回结果。
    • 语法:map(function, iterable)
    • 示例:
      numbers = [1, 2, 3, 4, 5]
      squared_numbers = list(map(lambda x: x**2, numbers))
      print(squared_numbers)  # 输出 [1, 4, 9, 16, 25]names = ["Alice", "Bob", "Charlie"]
      name_lengths = list(map(len, names))
      print(name_lengths)  # 输出 [5, 3, 7]
      

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux发行版比较:Ubuntu、CentOS、Red Hat与其他系统的优劣分析

导言 Linux作为开源操作系统,有众多不同的发行版,每个发行版都有其独特的特性和适用场景。本文将聚焦于比较Ubuntu、CentOS、Red Hat和其他系统,深入分析它们的优势、用途以及在不同领域的应用。Linux操作系统的生态系统中,Ubuntu…

SpringCloudAliBaba篇之Seata:分布式事务组件理论与实践

1、事务简介 事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。在关系数据库中,一个事务由一组SQL语句组成,事务具有4个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为ACID原则。 原子性(atomici…

【AI提示词专栏】提示词思维导图帮助

提示词重要作用 提示词,就像是我们生活中的“小助手”或者“贴心小棉袄”,总是在关键时刻给我们提供帮助和指引。它们就像那些无处不在的小标签,时刻提醒我们该做什么、不该做什么,或者给我们一些有趣的启示。 比如,在…

视觉SLAM中的相机分类及用途

视觉SLAM(Simultaneous Localization and Mapping)算法主要用于机器人和自动导航系统中,用于同时进行定位和建立环境地图。这种算法依赖于相机来捕捉环境数据。根据视觉SLAM的具体需求和应用场景,可以使用不同类型的相机。以下是用…

HarmonyOS4.0从零开始的开发教程19HarmonyOS应用/元服务上架

HarmonyOS(十七)HarmonyOS应用/元服务上架 概述 当您开发、调试完HarmonyOS应用/元服务,就可以前往AppGallery Connect申请上架,华为审核通过后,用户即可在华为应用市场获取您的HarmonyOS应用/元服务。 HarmonyOS会…

HTML_CSS的基本选择器的使用及其作用范围和优先级

目录 ✨CSS的使用:行内样式内部样式外部样式 ✨CSS基本选择器:id选择器class选择器标签选择器 ✨优先级:选择器的优先级样式表的优先级 ✨CSS的使用: 根据定义CSS的位置不同,分为行内样式、内部样式和外部样式 行内样…

数据库中对时间的操作(mySql、Oracle、pgSql)

目录 mySql PGSQL oracle 两个日期年数差 月数差 天数差 小时差 加一年 加一月 加一天 加一小时 加一分钟 加一秒 mySql -- %Y-%m-%d %H:%i:%s 区分大小写 m d i s小写 -- 两个日期年数差 SELECT TIMESTAMPDIFF(YEAR, STR_TO_DATE(2000-12-12,%Y-%m-%d), STR…

美颜SDK技术对比,深入了解视频美颜SDK的工作机制

如何在实时视频中呈现更加自然、美丽的画面,而这正是美颜SDK技术发挥作用的领域之一。本文将对几种主流视频美颜SDK进行深入比较,以揭示它们的工作机制及各自的优劣之处。 随着科技的不断进步,美颜技术已经从简单的图片处理发展到了视频领域…

Pandas中级教程——数据合并与连接

Python Pandas 中级教程:数据合并与连接 Pandas 是一款强大的数据处理库,提供了丰富的功能来处理和分析数据。在实际数据分析中,我们常常需要将不同数据源的信息整合在一起。本篇博客将深入介绍 Pandas 中的数据合并与连接技术,帮…

AI绘画室内设计提示词大全(持续更新)

当你开始使用AI绘画进行室内设计(interior design)时,选择合适的提示词和关键概念对于成功构思和实现你的设计理念至关重要。以下是一些关于室内设计的提示词,涵盖了空间类型、设计风格、光线效果、布局规划、材料类型以及其他要求…

硬件基础-电容

电容 本质:电容两端电压不能激变,所以可以起到稳定电压作用。充放电。 电容量的大小: 想使电容容量大:①使用介电常数高的介质 ②增大极板间的面积 ③减小极板间的距离。 品牌 国外:村田 muRata、松下 PANASONIC、三星 SAMSUNG、太诱 TAI…

sql_lab靶场搭建以及存在的一些问题

sql_lab靶场搭建问题 首先检查小皮版本 把小皮改到5.3.29版本如果没有可以直接点击更多版本进行选择安装 当版本不对时则会暴出这种错误 SETTING UP THE DATABASE SCHEMA AND POPULATING DATA IN TABLES: Fatal error: Uncaught Error: Call to undefined function mysql_co…

React面试题:Component,Element,Instance之间有什么区别和联系?

回答思路:分别是什么-->不同点-->相同点 Component(组件):一个组件可以通过多种方式声明,可以是带一个render()方法的类,也可以是一个函数,这两种情况下&#xff…

【QT】QTreeWidget控件的使用

目录 1.概述 2.QTreeWidget控件功能接口 2.1 构造函数 2.2 添加和访问顶级条目 2.3 条目访问函数 2.4 当前条目的操作 2.5 条目查找和排序 2.6 条目显示和运行时条目编辑 2.7 信号 2.8 槽函数 2.9 基类 QTreeView 的函数 2.10 树头条目 2.11选中行为和选中模式 3…

2018年第七届数学建模国际赛小美赛A题空中加油飞行计划解题全过程文档及程序

2018年第七届数学建模国际赛小美赛 A题 空中加油飞行计划 原题再现: 太平洋中部一个小岛上的居民被自然灾害困住。救援人员需要派遣一架轻型飞机运送少量急救药品到岛上,并运送一名重伤者到医疗基地求救。岛上有一个无人值守的简易机场,可以…

50ms时延工业相机

华睿工业相机A3504CG000 参数配置: 相机端到端理论时延:80ms 厂家同步信息,此款设备帧率上线23fps,单帧时延:43.48ms,按照一图缓存加上传输显示的话,厂家预估时延在:80ms 厂家还有…

基于Docker Compose的容器编排技术

1.1 介绍一下 Docker 建议我们每⼀个容器中只运⾏⼀个服务,因为 Docker 容器本身占⽤资源极少,所以最好是 将每个服务单独的分割开来但是这样我们⼜⾯临了⼀个问题? 如果我需要同时部署好多个服务,难道要每个服务单独写 Dockerf…

深入了解Linux信号:作用、产生、捕捉和阻塞

这里写目录标题 引言1. 信号的基本概念1.1 信号的分类和编号:1.2 查看信号默认处理动作1.3 信号的作用1.4 信号的产生 2. 常见信号及其作用示例 3. 信号捕捉和处理3.1 信号捕捉函数3.2 sigaction 函数示例 4. 信号阻塞示例 结语 引言 Linux操作系统中,信…

EM(Expectation-Maximum)算法

EM算法 简介 EM算法的核心分为两步 E步(Expection-Step)M步(Maximization-Step) 因为在最大化过程中存在两个参量 r , θ r,\theta r,θ,其中若知道 r r r,则知道 θ \theta θ;若知道 θ \…

mybatis一级缓存二级缓存和redis的区别

今天读到关于mybatis一级缓存、二级缓存的知识,然后看了一下mybatis一级缓存、二级缓存的应用场景,当时就感觉和redis很像,于是就查看了一下它们两个的区别。 Redis 和 MyBatis 一级缓存二级缓存的主要区别在于缓存的数据结构和存储方式上。…