当前位置: 首页 > article >正文

‘闭包‘, ‘装饰器‘及其应用场景

‘闭包’, '装饰器’及其应用场景

一, 闭包及其应用场景

图解

在这里插入图片描述

闭包的定义

概述: 内部函数 使用了 外部函数 的变量, 这种写法就称之为闭包.
格式:

def 外部函数名(形参列表):外部函数的(局部)变量def 内部函数名(形参列表):内部函数的(局部)变量return 内部函数名

前提条件:

  1. 有嵌套. 外部函数嵌套内部函数
  2. 有引用. 内部函数引用外部函数的变量
  3. 有返回. 外部函数中, 返回 内部函数名(对象)

细节:
函数名函数名() 是两个概念, 前者表示 函数对象 , 后者表示 调用函数, 获取返回值 .

案例

案例(1): 观察函数名函数名()
案例需求

创建函数, 分别打印函数名函数名()
证明: 函数名 -> 是对象, 函数名() -> 是调用函数, 获取返回值

实现思路
  1. 创建函数.
  2. 打印函数名.
  3. 打印函数名().
  4. 将函数名赋值给变量, 这个变量就是: 函数对象.
  5. 打印函数对象.
  6. 打印函数对象().
# 1. 创建函数.
def get_sum(a, b):return a + b
# 2. 打印函数名.
print(get_sum)	# <function get_sum at 0x000001B4AC3DD800>, 对象.
# 3. 打印函数名().
print(get_sum(10, 20))		# 调用函数, 获取返回值.# 4. 将函数名赋值给变量, 这个变量就是: 函数对象.
my_sum = get_sum
# 5. 打印函数对象.
print(my_sum)	# <function get_sum at 0x00000251CE53D800>
print(my_sum(100, 200))	# 300
案例(2): 闭包写法
案例需求

定义求和的闭包, 外部函数有参数num1, 内部函数有参数num2, 调用, 求解两数之和, 观察结果.

实现思路
  1. 定义外部函数.
  2. 定义内部函数.
  3. 求和.
  4. 调用上述函数.
  5. 另一种调用方式.
# 1. 定义外部函数.
def fn_outer(num1):# 2. 定义内部函数.def fn_inner(num2):					# 有嵌套# 3. 求和sum = num1 + num2				# 有引用print(f'求和结果: {sum}')return fn_inner						# 有返回# 4. 调用上述的函数.
fn_inner = fn_outer(10)
fn_inner(20)
# 5. 另一种调用方式.
fn_inner(100)(200)

二, nonlocal关键字介绍

nonlocal关键字的定义

nonlocal关键字是Python内置的关键字, 可以实现 在内部函数中 修改外部函数的 变量值.

图解

在这里插入图片描述

案例需求

编写1个闭包, 让内部函数访问外部函数的参数 a = 100, 并观察结果.

实现思路

  1. 定义外部函数.
  2. 定义外部函数的(局部)变量.
  3. 定义内部函数, 访问外部函数的变量.
  4. 在内部函数中修改外部函数的变量.
  5. nonlocal: 可以实现在内部函数修改外部函数的变量值.
  6. 打印外部函数的变量.
  7. 返回 内部函数名(对象).
# 1. 定义外部函数.
def fn_outer()# 2. 定义外部函数的(局部)变量.a = 100# 3. 定义内部函数, 访问外部函数的变量.def fn_inner()# 4. 在内部函数中修改外部函数的变量.# 5. nonlocal: 可以实现在内部函数中修改外部函数的变量值.nonlocal aa = a + 1# 6. 打印外部函数的变量.print(f'a: {a}')# 7. 返回 内部函数名(对象)return fn_inner# 8. 调用函数
fn_inner = fn_outer()
fn_inner()	# 101
fn_inner()	# 102
fn_inner()	# 103

三, 装饰器及其应用场景

装饰器的定义

概述:

装饰器的本质是1个闭包函数, 目的是 在不改变原有函数的基础上, 对1其功能做增强.
大白话: 装修队 在不改变房屋结构的情况下, 对房屋做装饰(功能增强).

提前条件:
  1. 有嵌套.
  2. 有引用.
  3. 有返回.
  4. 有额外功能.
格式:
  • 方法一: 传统写法.
修饰后的函数名 = 装饰器名(被装饰的原函数名)
装饰后的函数名()
  • 方法二: 语法糖.
在要被装饰的原函数上, 直接写 @装饰器名, 之后直接调用原函数即可.
图解:在这里插入图片描述

案例

案例(1): 发表评论.
案例需求

在发表评论前, 都是需要先登录的.

实现思路
  1. 定义外部函数, 形参列表接收 要被装饰的函数名(对象)
  2. 定义内部函数.
  3. 额外功能.
  4. 访问原函数, 即: 外部函数的引用.
  5. 返回内部函数对象.
  6. 定义函数, 表示 发表评论.
  7. 定义函数, 表示 充值中…
  8. 传统方式.
  9. 语法糖方式.
# 1.定义外部函数, 形参列表接收 要被装饰的函数名(对象)
def check_login(fn_name):       # fn_name: 被装饰的函数名(对象)# 2. 定义内部函数.def fn_inner():             # 有嵌套# 3. 额外功能print('校验登陆... 登陆成功!')# 4. 访问原函数, 即: 外部函数的引用.fn_name()               # 有引用# 5.  返回内部函数对象.return fn_inner             # 有返回# 6. 定义函数, 表示 发表评论.
def comment():print("发表评论")
# 7. 定义函数, 表示 充值中....
@check_login    # 底层其实是: payment = check_login(payment)
def payment():print('充值中...')# 8. 传统方式.
comment = check_login(comment)
comment()
# 9. 语法糖方式.
# payment = check_login(payment)
# payment()
payment()
案例(2): 装饰器装饰_无参无返回的原函数
细节

装饰器的内部函数格式 要和 被装饰的原函数 保持一致.
即:原函数是无参无返回的, 则 装饰器的内部函数也必须是 无参无返回的.
原函数有参有返回的, 则 装饰器的内部函数也必须是 有参有返回的.

案例需求

装饰器装饰_无参无返回的原函数

实现思路
# 需求: 定义无参无返回值的 get_sum()求和函数, 在不改变其代码的基础上, 添加友好提示: 正在努力计算中...
# 1. 定义装饰器.
def my_decorator(fn_name):# 2. 定义内部函数, 其格式必须和 被装饰的原函数 保持一致.def fn_inner():                 # 有嵌套# 3. 添加提示信息(额外功能)print('正在努力计算中...')     # 有额外功能# 4. 调用原函数.fn_name()                   # 有引用# 5. 返回内部函数(对象)return fn_inner                 # 有返回# 6. 定义原函数.
@my_decorator		# @装饰器名
def get_sum():a = 10b = 20sum = a + bprint(f'sum求和结果: {sum}')# 7. 传统方式.
# get_sum = my_decorator(get_sum)
# get_sum()# 8. 语法糖方式.
get_sum()
案例(3): 装饰器装饰_有参无返回值的原函数
细节

装饰器的内部函数格式 要和 被装饰的原函数 保持一致.
即:原函数是无参无返回的, 则 装饰器的内部函数也必须是 无参无返回的.
原函数有参有返回的, 则 装饰器的内部函数也必须是 有参有返回的.

案例需求

装饰器装饰_有参无返回值的原函数

实现思路
# 需求: 定义有参无返回值的 get_sum()求和函数, 在不改变其代码的基础上, 添加友好提示: 正在努力计算中...
# 1. 定义装饰器.
def my_decorator(fn_name):# 2. 定义内部函数def fn_inner(x, y):# 3. 额外功能print('正在努力计算中...')# 4. 调用原函数.fn_name(x, y)# 5. 返回内部函数.return fn_inner# 6. 定义原函数, 有参无返回值.
@my_decorator
def get_sum(a, b):sum = a + bprint(f'sum求和结果: {sum}')# 7. 传统方式.
# get_sum = my_decorator(get_sum)
# get_sum(10, 20)# 8. 语法糖方式.
get_sum(10, 20)

四, 总结

  • Q1:闭包的定义
    • 概述: 内部函数 使用了 外部函数 的变量, 这种写法就称之为闭包.
    • 格式:

相关文章:

‘闭包‘, ‘装饰器‘及其应用场景

‘闭包’, 装饰器’及其应用场景 一, 闭包及其应用场景 图解 闭包的定义 概述: 内部函数 使用了 外部函数 的变量, 这种写法就称之为闭包. 格式: def 外部函数名(形参列表):外部函数的(局部)变量def 内部函数名(形参列表):内部函数的(局部)变量return 内部函数名前提条件: …...

IDEA 快捷键ctrl+shift+f 无法全局搜索内容的问题及解决办法

本篇文章主要讲解IDEA、phpStrom、webStrom、pyCharm等jetbrains系列编辑器无法进行全局搜索内容问题的主要原因及解决办法。 日期&#xff1a;2025年3月22日 作者&#xff1a;任聪聪 现象描述&#xff1a; 1.按下ctrlshiftf 输入法转为了繁体。 2.快捷键ctrlshiftr 可以全局检…...

Java——Random库

一、作用 Random库——生成随机数 二、实现步骤 1.导包&#xff1a;import java.util.Random; #快捷键&#xff1a;“Random”回车键 2.取得随机数&#xff1a;Random 变量1 new Random(); 3.调用随机数&#xff1a;类型 变量2 变量1.nextInt(n); &#xff08;代表变量…...

【通过Groovy去热修复线上逻辑】1.执行线上数据修复 2.写工具

1.执行groovy // 实际执行的话, 我们是通过vue提交的 http://localhost:8080/groovy/execute?scriptimport com.example.groovytest.controller.LoginController; LoginController.num251222 还有个技巧: 而执行执行的&#xff0c;则是: 写的工具什么的&#xff0c;想直接使…...

Powershell WSL导出导入ubuntu22.04.5子系统

导出Linux子系统 导出位置在C盘下,根据自己的实际情况更改即可Write-Host "export ubuntu22.04.5" -ForegroundColor Green wsl --export Ubuntu-22.04 c:\Ubuntu-22.04.tar 导入Linux子系统 好处是目录可用在任意磁盘路径,便于迁移不同的设备之间Write-Host &quo…...

【005安卓开发方案调研】之Flutter+Dart技术开发安卓

基于2025年国内移动开发环境现状&#xff0c;结合多份行业分析报告和技术文档&#xff0c;对FlutterDart开发安卓应用的技术成熟度和生态适配性分析如下&#xff1a; 一、技术成熟度评估 1. 跨平台能力达到生产级标准 Flutter的Skia自渲染引擎和Dart的AOT/JIT双编译模式&…...

论文笔记(七十三)Gemini Robotics: Bringing AI into the Physical World

Gemini Robotics: Bringing AI into the Physical World 文章概括1. 引言2. Gemini 2.0的具身推理2.1. 具身推理问答&#xff08;ERQA&#xff09;基准测试2.2. Gemini 2.0的具身推理能力2.3. Gemini 2.0支持零样本和少样本机器人控制 3. 使用 Gemini Robotics 执行机器人动作3…...

AI + 医疗 Qwq大模型离线本地应用

通义千问Qwq-32b-FP16可用于社区医院、乡镇卫生院、诊所等小型医疗机构&#xff0c;替代专业合理用药系统&#xff0c;作为药品知识库&#xff0c;实现以下功能&#xff1a; 药品信息智能查询&#xff1a;检索药品的详细说明书、适应症、禁忌症、不良反应及药物相互作用等关键信…...

Vue 3 项目实现国际化指南 i18n

引言 在开发现代 Web 应用时&#xff0c;国际化&#xff08;Internationalization&#xff0c;简称 i18n&#xff09;已经成为一个不可或缺的功能。无论是面向全球用户的商业网站&#xff0c;还是需要支持多语言的企业应用&#xff0c;良好的国际化支持都能显著提升用户体验。本…...

元音辅音及其字母组合发音

文章目录 单元音长元音/ɑː//ɔ://u://i://ɜː/// 短元音/ʌ//ɒ//ʊ//ɪ//ə//e/ 双元音/eɪ//aɪ//ɔɪ//ɪə//eə//ʊə//əʊ//aʊ/ 辅音3个鼻辅音m n ŋ 5个独立浊辅音w j r l h 20个清浊相对的辅音s zʃ ʒf vθ p bt dk gts dztʃ dʒtr dr 以下是列举的部分字母组合…...

【Vitis AIE】FPGA图像处理 11 双线性插值 Bilinear Interpolation

双线性插值 https://github.com/Xilinx/Vitis-Tutorials/tree/2024.2/AI_Engine_Development/AIE/Design_Tutorials/11-Bilinear_Interpolation 简介 双线性插值是一种使用重复线性插值来插值两个变量函数的方法。它通常用于以下应用&#xff1a; 图像处理和计算机视觉&…...

Linux | 安装 Samba将ubuntu 的存储空间指定为windows 上的一个磁盘

01 安装 samba 文件来实现。比如把我们 ubuntu 的存储空间指定为我们 windows 上的一个磁盘,然后我们在这个磁盘里面创建 .c 文件,进行我们代码的修改和编写,可以安装 samba 文件来实现。 samba 是一种网络共享服务,可以通过网络访问我们指定的文件夹 02 第一步:下…...

一文说清预训练与微调:AI的双重训练法则

什么是预训练&#xff1f; 预训练是大型语言模型训练的第一步。它在资金和计算能力的支持下&#xff0c;通过深入分析大量的文本数据&#xff0c;使模型建立起语言的基本构架。在这一阶段&#xff0c;模型通过学习海量的书籍、文章和网页&#xff0c;识别出语言的语法、句法和…...

solana增加流动性和删除流动性

在 Solana 区块链上增加和删除流动性通常通过去中心化交易所&#xff08;DEX&#xff09;实现&#xff0c;例如 Raydium 或 Orca。以下是详细的操作流程和注意事项&#xff1a; 一、增加流动性 步骤&#xff1a; 1. 连接钱包 使用支持 Solana 的钱包&#xff08;如 Phantom、…...

996引擎-接口测试:音效测试NPC

996引擎-接口测试:音效测试NPC 参考资料local offset = 1 -- 默认偏移量function main(player, newOffset)offset = newOffset or offset -- 更新偏移量local buttonWidth =...

javabean类,测试类,工具类都是什么?

JavaBean类 用来描述一类事物的类。比如Student、Teacher、Dog、Cat 例如下面的这个就是JavaBean类 package com.hong.static01demo;public class Student {//姓名&#xff0c;年龄&#xff0c;性别private String name;private int age;private String gender;public stati…...

基于C8051F020单片机的液晶显示,LCD1602并口驱动,单片机并口驱动LCD1602

一、前言 LCD1602是一种广泛使用的字符型液晶显示模块&#xff0c;有8根数据线和3根控制线E&#xff0c;RS和R/W&#xff0c;8根数据线与单片机P6连接&#xff0c;3根控制线与使用P1口的P1.4、P1.5、P1.6连接&#xff0c;VO连接了P1.7&#xff0c;通过给P1.7赋值0或1&#xff…...

miniconda安装保姆级教程|win11|深度学习环境配置

一、官网安装miniconda miniconda官网&#xff1a;Miniconda - Anaconda 点击Download按钮 在红框位置输入邮箱并点击submit&#xff0c;下载链接将会发到邮箱中 邮箱中将会收到如图所示邮件&#xff0c;点击下载 选择windows对应的miniconda安装包 miniconda安装包安装完成如…...

算力100问☞第92问:为什么各地热衷建设算力中心?

目录 1、宏观分析 2、政府角度分析 3、投资者角度分析 在数字化浪潮中,各地对算力中心建设的热情高涨,这一现象背后潜藏着诸多深层次的原因,涵盖了经济、科技、社会等多个维度,且彼此交织,共同驱动着这一发展趋势。 1、宏观分析 从经济结构转型的底层逻辑来看,全球经…...

HTML字符实体笔记

一、概述 在HTML中&#xff0c;某些字符具有特殊含义&#xff0c;不能直接用于网页内容显示&#xff0c;需要使用字符实体来代替。字符实体分为两类&#xff1a;字符实体名称和字符实体编号。字符实体名称由&开头&#xff0c;后跟实体名称&#xff0c;以分号;结束&#xf…...

Linux shell脚本-概述、语法定义、自定义变量、环境变量、预设变量、变量的特殊用法(转义字符、单双引号、大小括号)的验证

目录 1.shell概述 1.1作为应用程序&#xff1a; 1.2 shell 作为一门语言 2.shell 语法 2.1 shell脚本的定义与执行 &#xff08;1&#xff09;新建文件 &#xff08;2&#xff09;程序开头第一行 必须写shell的类型 &#xff08;3&#xff09;程序编写完后&#xff0c…...

数据驱动进化:AI Agent如何重构手机交互范式?

如果说AIGC拉开了内容生成的序幕&#xff0c;那么AI Agent则标志着AI从“工具”向“助手”的跨越式进化。它不再是简单的问答机器&#xff0c;而是一个能够感知环境、规划任务并自主执行的智能体&#xff0c;更像是虚拟世界中的“全能员工”。 正如行业所热议的&#xff1a;“大…...

DL学习笔记:穿戴设备上的轻量级人体活动识别方法

Hello&#xff0c;大家好&#xff01;这里是《Dream 的深度学习笔记》,本系列将聚焦三个学习方面&#xff1a; 论文解读&#xff1a;拆解经典论文与最新突破 技术实现&#xff1a;从模型搭建到实际部署 应用案例&#xff1a;涵盖图像识别、深度学习、人工智能等热门方向 让…...

拓展知识三:编码学及密码学

编码和密码的区别 研究密码变化的客观规律&#xff0c;应用于编制密码以保守通信秘密的&#xff0c;称为编码学&#xff1b;应用于破译密码以获取通信情报的&#xff0c;称为破译学&#xff0c;总称密码学。 编码和密码是两个不同的概念&#xff0c;它们的区别如下&#xff1a;…...

windows安装配置FFmpeg教程

1.先访问官网&#xff1a;https://www.gyan.dev/ffmpeg/builds/ 2.选择安装包Windows builds from gyan.dev 3. 下滑找到release bulids部分&#xff0c;选择ffmpeg-7.0.2-essentials_build.zip 4. 然后解压将bin目录添加path系统变量&#xff1a;\ffmpeg-7.0.2-essentials_bui…...

Qt/C++项目积累:4.远程升级工具 - 4.1 项目设想

背景&#xff1a; 桌面程序一般都支持远程升级&#xff0c;也是比较常用的场景设计。如酷狗音乐的升级&#xff0c;会提供两个选项&#xff0c;自动帮助安装或是新版本提醒&#xff0c;由用户来决定是否升级&#xff0c;都属于远程升级的应用及策略。 看看经过这块的功能了解及…...

同旺科技USB to SPI 适配器 ---- 指令循环发送功能

所需设备&#xff1a; 内附链接 1、同旺科技USB to SPI 适配器 1、周期性的指令一次输入&#xff0c;即可以使用 “单次发送” 功能&#xff0c;也可以使用 “循环发送” 功能&#xff0c;大大减轻发送指令的编辑效率&#xff1b; 2、 “单次发送” 功能&#xff0c;“发送数据…...

用 Pinia 点燃 Vue 3 应用:状态管理革新之旅

一、状态管理的范式转移&#xff1a;从 Flux 到 Composition ### 1.1 Vuex 的辉煌与局限 - **核心架构**&#xff1a;基于Flux模式的state/mutations/actions三件套 - **痛点显现**&#xff1a; - 类型推导困难&#xff1a;TypeScript支持需复杂配置 - 模块嵌套陷阱&#…...

单表达式倒计时工具:datetime的极度优雅(Kimi)

一个简单表达式&#xff0c;也可以优雅自成工具。 笔记模板由python脚本于2025-03-22 20:25:49创建&#xff0c;本篇笔记适合任意喜欢学习的coder翻阅。 【学习的细节是欢悦的历程】 博客的核心价值&#xff1a;在于输出思考与经验&#xff0c;而不仅仅是知识的简单复述。 Pyth…...

Linux:基础IO---文件描述符

文章目录 1. 前言1.1 C语言文件知识回顾 2. 文件2.1 文件基础知识 3. 被打开的文件3.1 以C语言为主&#xff0c;先回忆一下C文件接口3.2 过渡到系统&#xff0c;认识文件系统调用3.3 访问文件的本质3.4 重定向&&缓冲区 序&#xff1a;在深入了解了进程的内容后&#xf…...