python中函数式编程与高阶函数,装饰器与生成器,异常处理与日志记录以及项目实战

函数式编程是 Python 强大且灵活的编程范式之一,与此同时,Python 也为开发者提供了高阶函数、装饰器、生成器等工具,极大提高了代码的可读性和复用性。此外,异常处理与日志记录是编写可靠、可维护的 Python 代码的重要组成部分。最后,通过一个项目实战来整合这些概念。

我们将从以下几个方向展开:

  1. 函数式编程与高阶函数
  2. 装饰器与生成器
  3. 异常处理与日志记录
  4. 项目实战:文件批量处理工具

一、函数式编程与高阶函数

1.1 函数式编程概念

函数式编程是一种编程范式,强调函数的不可变性和无副作用。Python 作为多范式编程语言,提供了函数式编程的支持。函数式编程中的核心概念包括:

  • 纯函数:函数的输出仅依赖输入,不依赖外部状态,且不会改变外部状态。
  • 不可变性:数据一旦创建便不可修改。
  • 高阶函数:可以接受函数作为参数或返回函数。

1.2 常见的高阶函数

map()

map() 函数将一个函数应用于一个可迭代对象中的每个元素,返回一个迭代器。

# 例子:将列表中的每个元素平方
numbers = [1, 2, 3, 4]
squares = list(map(lambda x: x**2, numbers))
print(squares)  # 输出: [1, 4, 9, 16]
filter()

filter() 函数用于过滤可迭代对象中符合条件的元素。

# 例子:过滤出列表中的偶数
numbers = [1, 2, 3, 4, 5, 6]
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens)  # 输出: [2, 4, 6]
reduce()

reduce() 来自 functools 模块,作用是将可迭代对象中的元素累计计算出一个值。

from functools import reduce# 例子:累积相乘列表中的元素
numbers = [1, 2, 3, 4]
product = reduce(lambda x, y: x * y, numbers)
print(product)  # 输出: 24

1.3 函数作为参数与返回值

Python 中函数是一等公民,可以作为参数传递,或作为返回值。

# 函数作为参数
def apply_function(func, value):return func(value)print(apply_function(lambda x: x + 2, 10))  # 输出: 12# 函数作为返回值
def outer_function():def inner_function():return "Hello from inner function!"return inner_functionhello_func = outer_function()
print(hello_func())  # 输出: Hello from inner function!

二、装饰器与生成器

2.1 装饰器

装饰器是一种函数,它用于在不改变原函数代码的情况下,扩展或修改函数的功能。装饰器通常用于函数的前后执行某些操作,比如记录日志、计时等。

装饰器基本用法
# 基本的装饰器函数
def my_decorator(func):def wrapper():print("在函数调用前")func()print("在函数调用后")return wrapper@my_decorator
def say_hello():print("Hello!")say_hello()
# 输出:
# 在函数调用前
# Hello!
# 在函数调用后
带参数的装饰器

装饰器也可以装饰带参数的函数:

def my_decorator(func):def wrapper(*args, **kwargs):print("在函数调用前")result = func(*args, **kwargs)print("在函数调用后")return resultreturn wrapper@my_decorator
def greet(name):print(f"Hello, {name}!")greet("Alice")
# 输出:
# 在函数调用前
# Hello, Alice!
# 在函数调用后

2.2 生成器

生成器 是一种特殊的迭代器,通过 yield 关键字逐步生成值,生成器不会一次性将所有值计算出来,而是按需生成,节省内存。

生成器函数
def my_generator():for i in range(3):yield igen = my_generator()
print(next(gen))  # 输出: 0
print(next(gen))  # 输出: 1
print(next(gen))  # 输出: 2
生成器表达式

与列表推导式类似,生成器表达式使用小括号代替方括号:

gen = (x**2 for x in range(3))
for val in gen:print(val)
# 输出:
# 0
# 1
# 4

三、异常处理与日志记录

3.1 异常处理

异常处理是编写健壮代码的重要手段。通过 tryexceptfinally 语句捕获异常并处理,防止程序崩溃。

异常处理基本语法
try:result = 10 / 0
except ZeroDivisionError as e:print(f"发生错误: {e}")
finally:print("无论是否有异常,我都会执行")
自定义异常

可以通过继承 Exception 类创建自定义异常:

class CustomError(Exception):passdef raise_error():raise CustomError("自定义异常发生了!")try:raise_error()
except CustomError as e:print(e)

3.2 日志记录

使用 logging 模块记录程序执行的关键信息。

基本的日志记录
import logginglogging.basicConfig(level=logging.INFO)def divide(a, b):try:result = a / blogging.info(f"成功计算: {a} / {b} = {result}")return resultexcept ZeroDivisionError:logging.error("除数不能为零!")divide(10, 2)  # 输出日志: 成功计算: 10 / 2 = 5.0
divide(10, 0)  # 输出日志: 除数不能为零!
日志文件记录
logging.basicConfig(filename='app.log', level=logging.INFO)logging.info("程序启动")

四、项目实战:文件批量处理工具

项目简介

需求:开发一个工具来批量处理多个文件。假设我们有大量文本文件,内容是多个数字,我们需要统计每个文件的平均值,并将结果写入日志文件中。

项目设计思路

  1. 读取文件:从目录中读取所有文本文件。
  2. 处理文件内容:解析每个文件中的数字,计算平均值。
  3. 记录日志:将每个文件的处理结果记录到日志中。

项目代码实现

1. 读取文件列表
import osdef get_files_from_directory(directory):return [f for f in os.listdir(directory) if f.endswith('.txt')]
2. 处理文件内容
def process_file(filepath):with open(filepath, 'r') as file:numbers = [int(line.strip()) for line in file.readlines()]return sum(numbers) / len(numbers) if numbers else 0
3. 日志记录与异常处理
import logginglogging.basicConfig(filename='file_processing.log', level=logging.INFO)def log_result(filename, result):logging.info(f"文件 {filename} 的平均值为: {result}")
4. 整合代码
def main():directory = './files'files = get_files_from_directory(directory)for file in files:try:filepath = os.path.join(directory, file)result = process_file(filepath)log_result(file, result)except Exception as e:logging.error(f"处理文件 {file} 时发生错误: {e}")if __name__ == "__main__":main()

运行结果

  1. 所有文件的平均值会记录到 file_processing.log 文件中。
  2. 如果有任何文件处理失败,日志中会有详细的错误信息。

总结

通过这个项目,我们整合了 Python 的函数式编程、高阶函数、装饰器、生成器,以及异常处理与日志记录的概念。这个工具展示了如何结合这些强大的特性来编写简洁、优雅且高效的代码。

Python 提供了极大的灵活性和可扩

展性,通过充分利用这些工具和技术,可以轻松应对各种复杂的任务。你可以根据项目需求,进一步扩展这个工具,例如添加并行处理文件的功能,或者通过命令行参数动态配置输入输出目录。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

修改 Visual Studio 的主题颜色、背景颜色、字体

本人使用的是 VS2019 版本的。 点击上方工具栏中的【工具】-> 【选项】。 在 【环境】->【常规】中,可以更改整个界面的主题颜色。 浅色和深色的主题如下: 在【环境】->【字体和颜色】中,可以更改代码区的背景色。 不同背景示例&…

RK3568笔记六十:V4L2命令测试

若该文为原创文章,转载请注明原文出处。 测试V4L2是想移植韦老师的相机程序,但他使用的是V4L2方式采集摄像头。 而正点原子的rknn使用的是opencv。 这里记录测试过程 一、常用调试命令 1、抓取图像 使用 v4l2-ctl 抓取一帧图像:v4l2-ctl -d /dev/video0 --set-fmt-video…

计算机图形学 中心画圆算法 原理及matlab代码实现

中心画圆算法原理 总体思路: 将圆划分为八部分,先通过diF(xi1,yi-0.5)和隐函数Fx2y2-R2绘制八分之一的圆,然后通过圆的对称性确定另外七个部分的相应坐标绘制完整的圆。 求中点误差项递推公式: 从(x0,y0r)开始,因绘…

嵌入式流媒体SRT协议:send buffer和窗口延迟机制

Handshake Packets: 握手控制包(“包类型”位 1)用于在点对点的 SRT 会话中建立两个对等体之间的连接。早期版本的 SRT 依赖于握手扩展来在连接建立后立即交换某些参数,但自 1.3 版本起,集成机制确保所有参数作为握手…

Python使用YOLOv5图像识别教程包成功-以识别桥墩缺陷详细步骤分享

前置环境资源下载 提示:要开外网才能下载的环境我都放在了网盘里,教程中用到的环境可从这里一并下载: https://pan.quark.cn/s/f0c36aa1ef60 1. 下载YOLOv5源码 官方地址:GitHub - ultralytics/yolov5: YOLOv5 🚀 …

9。maven必备小技巧

(1)配置Maven加速时,除了settings之外,还可如下图所示,配置如下: 若想实现Maven加速,最重要的即User settings file。(先修改settings.xml) (2)当…

哪个牌子的头戴式耳机性价比高?四大爆款性价比品牌推荐!

随着科技的不断进步和发展,头戴式耳机已经成为音乐爱好者和专业人士不可或缺的设备。进入2024年,市场上涌现出了一批性能卓越、音质优秀的新产品。这些新品不仅在音质上有了显著的提升,还在设计、舒适度和功能性上进行了全面的优化&#xff0…

(科普篇)公司防止泄密,应该做到哪些?教你10个方法有效阻止泄密事件发生!

公司防止泄密,应该做到哪些? 世事如棋局局新,信息之海波涛汹涌! 甲曰:"企业之基,在于保密。泄密之祸,猛于虎也,如何防患于未然。吾友,可有良策?" …

lettuce引起的Redis command timeout异常

项目使用Lettuce,在自己的环境下跑是没有问题的。在给客户做售前压测时,因为客户端环境比较恶劣,service服务和中间件服务不在同一机房。服务启动后不一会就会出现Redis command timeout异常。 经过差不多两周的追查,最后没办法把…

机器学习的应用领域

机器学习在许多领域有广泛的应用,下面列出了一些主要的应用领域及其典型应用: 1. 图像识别 人脸识别:用于解锁手机、自动标记照片、监控安全系统。物体识别:应用于自动驾驶汽车、机器人、医疗影像分析中,帮助机器理解…

三分钟 ChatGPT 接入钉钉机器人

前言 ChatGPT 大家应该都已经用了一段时间了,功能非常强大,作为开发人员,我用它写文档、写日报、润色 OKR,知识搜索等等,它给我带来了极大的帮助,但我在使用过程中最大的痛点就是网络。 痛点 由于国内不…

Java_Se--方法

方法就是一个代码片段. 类似于 C 语言中的 "函数"。方法存在的意义(不要背, 重在体会): 1. 是能够模块化的组织代码 ( 当代码规模比较复杂的时候 ). 2. 做到代码被重复使用 , 一份代码可以在多个位置使用 . 3. 让代码更好理解更简单 . 4. 直接调用现有方法开…

搭建WSL2+Ubuntu22.04 LTS环境

一、BIOS 开启虚拟化支持 现在的主板一般都默认开启的,也可以检查和开启BIOS虚拟化支持 二、windows开启子系统及虚拟化 打开控制面板 选择 程序 -> 启用或关闭 Windows功能 勾选 Hyper-V、适用于 Linux的 Windows子系统和虚拟机平台 点击确定 重启计算…

【近源攻击】badusb上线cs

❤️博客主页: iknow181 🔥系列专栏: 网络安全、 Python、JavaSE、JavaWeb、CCNP 🎉欢迎大家点赞👍收藏⭐评论✍ 0x01 实验前提 攻击设备:badusb cs服务器:公网部署了 cs 服务端 0x02 实验步骤 …

【计算机网络】理解应用层协议HTTP

目录 HTTP协议认识URLHTTP协议的请求如果我们想获得请求报文的完整内容,怎么办? HTTP协议的响应HTTP的方法GETvsPOST HTTP的状态码HTTP常见HeaderHTTP版本实现一个简单的HTTP服务器 HTTP协议 HTTP协议是一种超文本传输协议,它定义了客户端与…

Kafka 3.0.0集群部署教程

1、集群规划 主机名 ip地址 node.id process.roles kafka1 192.168.0.29 1 broker,controller Kafka2 192.168.0.30 2 broker,controller Kafka3 192.168.0.31 3 broker,controller 将kafka包上传以上节点/app目录下 mkdir /app 解压kafka包 tar -zxvf kafka_…

java之斗地主部分功能的实现

今天我们要实现斗地主中发牌和洗牌这两个功能,该如何去实现呢? 1.创建牌类:52张牌每一张牌包含两个属性:牌的大小和牌的花色。 故我们优先创建一个牌的类(Card):包含大小和花色。 public class Card { //单张牌的大小及类型/…

伊犁-linux 硬盘添加,分区,格式化

主要是linux 下操作硬盘分区,格式化 这样1个sata 盘就添加成功了 !  继续添加三块 sata1 hda sata hdb sata hdc sata hdd scsi sda 作为启动盘 进行操作系统的引导 如果scsi 往下调整 先敲enter 在用- 号往下 如果是往上调整敲…

【IDEA】使用IDEA连接MySQL数据库并自动生成MySQL的建表SQL语句

前言: 在软件开发过程中,数据库的设计与实现是至关重要的一环。IntelliJ IDEA作为一款强大的集成开发环境(IDE),提供了丰富的数据库工具,使得连接MySQL数据库并自动生成建表SQL语句变得简单快捷。本文将详细…

《python语言程序设计》2018版第8章18题几何circle2D类(上部)

一、利用第7章的内容来做前5个点 第一章之1--从各种角度来测量第一章之2--各种结果第二章之1--建立了针对比对点在圆内的几段第二章之2--利用建立的对比代码,得出的第2点位置 第一章之1–从各种角度来测量 class Circle2D:def __init__(self, x, y, radius):self._…