一、变量作用域基础

在 Python 中,变量根据作用范围可分为三类:

  1. 全局变量:定义在函数外部的变量,作用范围是整个程序。如果在函数内部需要修改全局变量,必须使用global关键字声明。

  2. 局部变量:定义在函数内部的变量,仅在该函数内部有效。需要注意的是,这是在不存在内部函数的前提下。

  3. 非局部变量:从内部函数的角度来看,外部函数中定义的变量称为非局部变量。当内部函数需要修改非局部变量时,必须使用nonlocal关键字进行声明。

二、闭包的概念与构成条件

闭包是 Python 中一个重要的概念,它满足以下三个条件:

  • 外部函数嵌套内部函数
  • 内部函数被返回
  • 内部函数访问外部函数的非局部变量

闭包的优缺点

优点

  • 可以避免全局变量被污染
  • 是实现装饰器的基础

缺点

  • 外部函数的非局部变量会一直被内部函数引用,导致变量长时间得不到回收,可能造成内存泄漏
  • 内存泄漏与内存溢出不同:内存泄漏是指数据无法回收,无法释放内存;内存溢出则是指空间不够用,数据溢出

注意:闭包虽有其用途,但应遵循 "能不用就不用" 的原则

三、闭包实战案例

案例 1:带限制的年龄增长函数

def outter():a = 10  # 局部变量age = 1  # 非局部变量def inner(n):nonlocal age  # 声明使用外部函数的非局部变量ageif age + n < 120:age += nreturn agereturn '数据不合法'return inner  # 返回内部函数# 调用方式:先获取内部函数,再调用内部函数
print(outter()(8))  # 输出:9

在这个案例中:

  • outter()是外部函数,inner(n)是内部函数
  • age是外部函数的变量,对内部函数来说是是非局部变量
  • 内部函数inner(n)访问并修改了非局部变量age
  • 外部函数返回了内部函数,形成了闭包
  • 该闭包实现了年龄增长的功能,并限制年龄不超过 120

案例 2:实现计数器功能

# 实现计数器
def outter1():a = 1  # 初始值def inner1(n):nonlocal a  # 声明使用外部函数的非局部变量aa += n  # 累加n值return areturn inner1  # 返回内部函数,不要加括号# 使用计数器
o = outter1()  # 获取内部函数
print(o(1))  # 输出:2
print(o(1))  # 输出:3
print(o(1))  # 输出:4
print(o(1))  # 输出:5
print(o(1))  # 输出:6

这个计数器案例很好地展示了闭包的特性:

  • 变量a被保存在闭包环境中,不会随着外部函数的执行结束而销毁
  • 每次调用内部函数,都会基于上一次的结果进行计算
  • 不需要使用全局变量就能实现状态的保持,避免了全局变量污染

四、总结

        闭包是 Python 中一个强大的特性,它通过外部函数嵌套内部函数,并让内部函数引用外部函数的变量,同时返回内部函数,实现了数据的封装和状态的保持。

        合理使用闭包可以提高代码的封装性和安全性,但也要注意其可能带来的内存问题。在实际开发中,应根据具体场景权衡使用,遵循 "必要时才使用" 的原则。

        掌握闭包不仅有助于理解 Python 的变量作用域,也是学习装饰器等高级特性的基础。希望通过本文的讲解和案例,能帮助大家更好地理解和运用 Python 闭包。

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

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

相关文章

Docker 跨主机容器之间的通信macvlan

默认一个物理网卡&#xff0c;只有一个物理mac地址&#xff0c;虚拟多个mac地址 缺点&#xff1a;每次需要手动配置ip地址&#xff0c;容易ip地址冲突。类似于保存到execl表格里面。 两台物理机&#xff1a; docker-01和docker-02 创建macvlan网络 [rootdocker-01 ~]# docker n…

android 换肤框架详解1-换肤逻辑基本

android 换肤框架详解1-换肤逻辑基本-CSDN博客 android 换肤框架详解2-LayoutInflater源码解析-CSDN博客 android 换肤框架详解3-自动换肤原理梳理-CSDN博客 换肤框架流程 1&#xff0c;通过AssetManager获取换肤的资源文件 2&#xff0c;通过原文件中的resId获取到res名称…

NEON性能优化总结

转自 NEON优化&#xff1a;性能优化经验总结-CSDN博客 NEON优化&#xff1a;性能优化经验总结 1. 什么是 NEON Arm Adv SIMD 历史 2. 寄存器 3. NEON 命名方式 4. 优化技巧 5. 优化 NEON 代码(Armv7-A内容&#xff0c;但区别不大) 5.1 优化 NEON 汇编代码 …

计算机网络摘星题库800题笔记 第2章 物理层

第2章 物理层2.1 物理层概述题组闯关1.采用以下哪种设备&#xff0c;可以使数字信号传输得更远 ( )。 A. 放大器 B. 中继器 C. 网桥 D. 路由器1.【参考答案】B 【解析】选项 A 放大器只是单纯地放大信号、抑制噪音和干扰。选项 B 中继器是把一根线缆中的电或者光信号传递给另一…

导入文件到iPhone实现

我们有时候开发需要加载一些自己的文件&#xff0c;这个时候就需要导入文件到iPhone等设备。在info里面open as source code&#xff0c;加入如下配置&#xff1a;<!-- 开启 iTunes / Finder 文件共享 --><key>UIFileSharingEnabled</key><true/>或者o…

Ubuntu Server系统安装磁盘分区方案

最近打算把家里的旧电脑利用起来&#xff0c;装上Ubuntu Server 24.04.3 LTS作为一个家用NAS服务器&#xff0c;但是给旧电脑安装系统时遇到了一些问题&#xff0c;遂记录下来 GPT分区与MBR分区 GPT 指的是 GUID Partition Table&#xff08;全局唯一标识分区表&#xff09;&am…

1小时 MySQL 数据库基础速通

目录 一、MySQL安装配置 1、下载mysql 2、下载mysql-shell 二、MySQL基本概念 1. 数据库&#xff08;Database&#xff09; 2. 表&#xff08;Table&#xff09; 3. 数据类型&#xff08;Data Type&#xff09; 4. 主键&#xff08;Primary Key&#xff09; 5. 索引&am…

HTTP应用层协议-长连接

HTTP应用层协议-长连接 关于 connection 报头 HTTP 中的 Connection 字段是 HTTP 报文头的一部分&#xff0c;它主要用于控制和管理客户端与服务器之间的连接状态 核心作用 • 管理持久连接&#xff1a;Connection 字段还用于管理持久连接&#xff08;也称为长连接&#xff09;…

2020/12 JLPT听力原文 问题一 4番

4番&#xff1a;ホテルの受付で女の人と男の人が話しています。女の人はどこでパソコンを使いますか。女&#xff1a;すみません、パソコンの貸出ってできますか。部屋で仕事をしたいんですけど。 男&#xff1a;申し訳ございません。貸出はしていないんですが、二階にビジネス…

《在 Spring Boot 中安全使用 Qwen API-KEY:环境变量替代明文配置的最佳实践》

《在 Spring Boot 中安全使用 Qwen API-KEY&#xff1a;环境变量替代明文配置的最佳实践》 想要的效果其实就是 把 Qwen API-KEY 放到系统环境变量中&#xff0c;然后在 application.yml 里通过占位符读取&#xff0c;而不写明文。 这样即便 application.yml 被提交到 Git&…

Nginx 反向代理与负载均衡架构

一、反向代理基础 实验目的&#xff1a;通过 Nginx 反向代理&#xff0c;将客户端请求按类型&#xff08;静态页面 / 动态 PHP 页面&#xff09;转发到不同的后端服务器&#xff08;RS1 处理静态资源&#xff0c;RS2 处理动态请求&#xff09;&#xff0c;实现 “客户端只与代…

【Mybatis入门】配置Mybatis(IDEA)

Mybatis和JDBC一样&#xff0c;是连接数据库的工具。它是一款优秀的持久层框架&#xff0c;主要用于 Java 语言中简化数据库操作&#xff0c;实现对象与数据库表之间的映射。Mybatis相比于JDBC的优势Mybatis消除了传统 JDBC 代码中繁琐的手动处理、参数设置、结果集解析等重复工…

多路转接之epoll 【接口】【细节问题】【LT与ET模式】【Reactor】

目录 一.接口 1.1epoll_creaet 1.2epoll_ctl 1.3epoll_wait 二.细节问题 2.1 工作原理 2.2 epoll的demo 2.3 epoll的优点 三. LT 与 ET模式 理解ET 四. reactor 一.接口 1.1epoll_creaet 注意返回值是一个文件描述符 创建一个epoll模型 1.2epoll_ctl 返回值&…

渗透测试现已成为 CISO 战略的核心

随着数字供应链的扩展以及生成式人工智能在关键系统中的嵌入&#xff0c;安全领导者正在重新思考其网络安全策略。Emerald Research 最近对 225 位安全领导者进行的一项调查发现&#xff0c;68% 的人担心第三方软件和组件带来的风险。虽然大多数受访者表示他们正在满足监管要求…

音视频学习(五十三):音频重采样

概述 音频重采样&#xff08;sample rate conversion, SRC&#xff09;是把采样率从 Fs_in 变换为 Fs_out 的过程。常见场景有格式转换&#xff08;44.1→48 kHz&#xff09;、采样率匹配&#xff08;播放链路统一采样率&#xff09;、以及通信中语音采样率升降&#xff08;8 k…

【C#】正则表达式

一、核心优势&#xff1a;用一小段规则搞定大量复杂的字符串匹配&#xff0c;查找和替换&#xff0c;并且可移植可复用。使用正则表达式的好处&#xff1a;1. 强大且灵活&#xff1a;可以一次性匹配非常复杂的规则&#xff0c;比如验证邮箱、提取特定的格式日志、解析URL&#…

【[特殊字符][特殊字符] 协变与逆变:用“动物收容所”讲清楚 PHP 类型的“灵活继承”】

你有没有遇到过这样的问题&#xff1a;“为什么子类方法可以返回 Cat&#xff0c;而父类只写了返回 Animal&#xff1f;” “为什么参数反而能从 CatFood 变成更宽泛的 Food&#xff1f;”这些看似“违反直觉”的设计&#xff0c;其实背后有一个优雅的编程概念&#xff1a;协变…

cesium/resium 修改子模型材质

我是 www.v2ex.com/t/1151549 的作者&#xff0c;在csdn这边补全一些更多的信息 相关工具 主项目插件版本&#xff1a; "cesium": "^1.131.0",、"resium": "^1.19.0-beta.1"、"three": "^0.178.0"、"react…

nvm install 14.21.3 时npm 无法下载和识别

错误&#xff1a;C:\Users\H3C>nvm install 14.21.3 Downloading node.js version 14.21.3 (64-bit)... Complete Downloading npm... Creating C:\Users\H3C\AppData\Local\Temp\nvm-install-939491942\temp Downloading npm version 6.14.18... Error while downloading h…

【网络运维】Linux:LNMP 项目实践

LNMP 项目实践 简介&#xff1a;什么是 LAMP/LNMP LAMP&#xff1a;LinuxApacheMysql/MariadbPHP/Python/Perl。 LNMP&#xff1a;LinuxNginxMysql/MariadbPHP/Python/Perl。 Linux&#xff1a;操作系统&#xff0c;提供程序运行基础。Apache/Nginx&#xff1a;Web 服务器&…