Python闭包与装饰日高级概念

embedded/2024/9/25 3:07:06/

在Python中,闭包(Closure)和装饰器(Decorator)是两个高级且强大的编程概念,它们在函数式编程和面向对象编程中扮演着重要角色。下面将详细讲解这两个概念。

一、闭包(Closure)

1. 定义

闭包是指一个函数记住了其创建时的环境(即函数外部作用域中的变量),即使这个函数在其外部作用域之外被调用,它仍然能够访问这些变量。简单来说,闭包是一个函数以及该函数创建时所处的环境的组合。

2. 特性
  • 嵌套函数:闭包通常涉及一个外部函数和一个或多个内部函数,内部函数可以访问外部函数的局部变量。
  • 返回内部函数:外部函数返回内部函数,这个返回的内部函数就是闭包。
  • 访问外部变量:即使外部函数已经执行完毕,闭包仍可以访问并操作外部函数的局部变量。
3. 示例
 

python复制代码

def outer_function(x):
def inner_function(y):
return x + y
return inner_function
closure = outer_function(2) # 闭包记住了x=2
result = closure(3) # 调用闭包,返回5
print(result) # 输出: 5

在这个例子中,outer_function是一个外部函数,它定义了一个局部变量x和一个内部函数inner_functionouter_function返回了inner_function的引用,这个引用就是一个闭包,因为它记住了x的值。

4. 应用场景
  • 数据封装:闭包可以用于封装数据和操作这些数据的函数,类似于对象。
  • 延迟计算:闭包可以延迟执行某些计算,直到实际需要结果时。
  • 回调函数:在事件驱动编程中,闭包常用于定义回调函数,携带额外的参数。

二、装饰器(Decorator)

1. 定义

装饰器是一种特殊的函数,它接受一个函数作为参数,并返回一个新的函数或修改原来的函数。装饰器的本质是一个闭包函数,它允许在不修改原始函数代码的情况下给函数添加新的功能。

2. 基本语法
 

python复制代码

def decorator(func):
def wrapper(*args, **kwargs):
# 在调用原始函数之前可以做一些事情
result = func(*args, **kwargs)
# 在调用原始函数之后可以做一些事情
return result
return wrapper
@decorator
def original_function():
# 原始函数体
pass
3. 使用方法

使用装饰器非常简单,只需要在函数定义之前使用@符号加上装饰器的名称即可。当调用被装饰的函数时,实际上是调用了装饰器返回的wrapper函数。

4. 进阶用法
  • 带参数的装饰器:装饰器本身也可以有参数,这种情况下需要定义一个外层函数,它接收装饰器的参数,并返回一个装饰器。
  • 类装饰器:除了函数装饰器外,Python还支持使用类作为装饰器。类装饰器必须实现__init____call__两个特殊方法。
5. 示例
 

python复制代码

def my_decorator(func):
def wrapper(*args, **kwargs):
print("Something before the function is called.")
result = func(*args, **kwargs)
print("Something after the function is called.")
return result
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
# 输出:
# Something before the function is called.
# Hello!
# Something after the function is called.

在这个例子中,my_decorator是一个装饰器,它接受一个函数say_hello作为参数,并返回一个新的函数wrapper。当调用say_hello()时,实际上是调用了wrapper(),从而在say_hello()函数执行前后打印了额外的信息。

总结

闭包和装饰器是Python中两个非常重要的高级概念,它们使得Python代码更加灵活、强大和易于维护。闭包通过记住其创建时的环境,实现了对外部变量的访问和操作;而装饰器则通过在不修改原始函数代码的情况下给函数添加新的功能,提高了代码的复用性和可维护性。


http://www.ppmy.cn/embedded/116411.html

相关文章

如何使用ssm实现基于VUE的儿童教育网站的设计与实现+vue

TOC ssm676基于VUE的儿童教育网站的设计与实现vue 第一章 课题背景及研究内容 1.1 课题背景 信息数据从传统到当代,是一直在变革当中,突如其来的互联网让传统的信息管理看到了革命性的曙光,因为传统信息管理从时效性,还是安全…

vue3开发中易遗漏的常见知识点

文章目录 组件样式的特性Scoped CSS之局部样式的泄露Scoped CSS之深度选择器CSS Modules在CSS中使用v-bind 非props属性继承组件通信父子组件的相互通信props/$emit父组件传递数据给子组件子组件传递数据给父组件 非父子组件的相互通信Provide/inject全局事件总线 组件插槽作用…

WPF 控件数据源绑定

WPF 控件数据源绑定 前提:我的数据源都放在 DataProcessView 类中,然后在 MainWindow 中声明该类的对象 DataProcess,如果是指定了 DataContext ,就将该对象赋值给 DataContext (如下),否则不赋…

SpringBoot基础知识

谈一谈你对SpringBoot的理解,它有哪些特性(优点)? SpringBoot用来快速开发Spring应用的一个脚手架,其目的是用来简化新Spring应用的初始搭建以及开发过程。 优点: 简化配置:提供了很多内置的…

工作笔记:Vue 3 中使用 vue-router 进行导航与监听路由变化

一、使用 useRouter 进行导航 在 Vue 3 组件中&#xff0c;你可以使用 useRouter 来方便地进行页面导航。以下是一个简单的示例&#xff1a; <template><button click"navigateToHome">跳转到首页</button> </template><script setup&g…

使用HID硬件实现自动化脚本防检测、防风控

我们在做自动化脚本的过程中&#xff0c;经常会遇到风控问题&#xff0c;比如游戏脚本&#xff0c;视频脚本等。有些app会检测手机是否root、是否开启调试模式、是否开启无障碍模式。如果我们使用的平台有开启这些就有可能被检测到&#xff0c;我们可以使用HID硬件来模拟外接键…

IDE配置Java注释模板

步骤很详细&#xff0c;直接上教程 一. 配置类注释 /** * ClassName : ${NAME} * Description : ${description} * Author : [Your Name] * Date: ${YEAR}-${MONTH}-${DAY} ${HOUR}:${MINUTE} */效果演示 二. 配置方法注释 **$params$* return * Author: Amoorzheyu *…

CentOS Linux教程(7)--目录文件的创建、删除、移动、复制、重命名

文章目录 1. 创建目录、文件2. 删除目录、文件3. 移动目录、文件4. 复制目录、文件5. 重命名目录、文件 1. 创建目录、文件 使用mkdir创建目录&#xff1a; 使用touch创建文件&#xff1a; 2. 删除目录、文件 使用rm可以删除文件: 使用rm -f可以强制删除文件&#xff0c;…