网站首页 > 技术文章 正文
什么是嵌套函数
Python中嵌套函数,也称作内部函数,是在函数内部定义的函数。需要注意的是:
- 外部函数的变量可以被内部函数所使用,但不能被内部函数修改
- 若一定要修改,需要添加nonlocal关键字,使用了nonlocal关键字,将变量标记为不在本地作用域定义,而在上一级局部作用域中定义,但不能是全局作用域中定义。nonlocal只能用在嵌套函数的内部
嵌套函数的作用
嵌套函数主要用于:
- 数据隐藏:外部无法访问嵌套函数及嵌套函数内的变量;
- 利用代码:外部函数内有多个地方逻辑处理相同,因此在其内部定义函数可以减少重复代码;
- 闭包原则: 在很多编程语言中都存在闭包的概念,那什么是闭包呢?闭包其实就是一个概念,出现在嵌套函数中,指的是:内层函数引用到了外层函数的自由变量,就形成了闭包。
自由变量:未在本地作用域中定义的变量,比如在嵌套函数的外层定义的变量(非全局变量),对内层来说,这个变量就叫做自由变量。
嵌套函数使用
# 函数的闭包: 在函数内部对嵌套函数进行返回操作称之为闭包
def outer():
def inner():
print('我是内部inner在打印')
return inner # 注:这里是返回inner的引用,不能加(),加了相当于调用inner
# 那怎样才能正确调用outer呢?
# 通过下面这行代码调用outer(), 返回的inner的引用, 所以这不是正确的调用方式
print(outer()) # <function outer.<locals>.inner at 0x7fb5702eccb0>
# 下面这行代码才是正确地调用outer的方式
# 首先outer()返回了inner()的地址引用, 然后再调用
outer()() # 我是内部inner在打印
# 上面的代码相当于
f_innter = outer()
f_innter() # 我是内部inner在打印
嵌套函数用于函数装饰器(三层嵌套)
函数装饰器,是指在不改变某一函数(outer)的情况下,增强另一个函数的功能(inner),这种在代码运行期间动态增加功能的方式,称之为“装饰器”。
下面通过代码示例来逐步模拟“装饰器”的实现过程:
- 1.定义嵌套函数,外层函数接收一个外部函数的引用,在内部函数中调用外部传入的函数
def cartel(f):
def doperunner():
print('贩毒小团伙内部开始计划...')
f() #调用外部传入内部函数的逻辑,f的功能由传入的函数定义
print('贩毒小团伙内部开始行动...')
return doperunner
# 定义要传入的函数
def spy():
print(f'我要把间谍注入贩毒集团下的分部')
print(f'间谍开始收集情报')
print(f'间谍回馈情报')
print(f'总部收到间谍情报,得知小团伙近期行动计划,开始布署')
# 在本例中,cartel相当于一个闭包的函数,比较特殊的是它提供了一个接口f。
# 这个参数是函数,因此,要调用cartel函数,要通过以下方法:
f = cartel(spy)
f()
2.Python语法糖@改进调用方法
def cartel(f):
def doperunner():
print('贩毒小团伙内部开始计划...')
f() #调用外部传入内部函数的逻辑,f的功能由传入的函数定义
print('贩毒小团伙内部开始行动...')
return doperunner
# 语法糖
@cartel
# 定义要传入的函数
def spy():
print(f'我要把间谍注入贩毒集团下的分部')
print(f'间谍开始收集情报')
print(f'间谍回馈情报')
print(f'总部收到间谍情报,得知小团伙近期行动计划,开始布署')
#========>等同于 f = cartel(spy) f()
spy()
函数带参数的装饰器
def cartel(f):
def doperunner(*args, **kwargs):
print('贩毒小团伙内部开始计划...')
f(*args,**kwargs) #调用外部传入内部函数的逻辑,f的功能由传入的函数定义
print('贩毒小团伙内部开始行动...')
return doperunner
# 语法糖
@cartel
def spy(*args, **kwargs):
for name in args:
print(f'把间谍{name}注入贩毒集团下的分部')
print(f'间谍{name}开始收集情报')
print(f'间谍{name}回馈情报')
print(f'总部收到间谍{name}情报,得知小团伙近期行动计划,开始布署')
if kwargs:
print(kwargs)
# 调用
spy(['梁朝伟','刘嘉玲'])
装饰器带参数
def is_exposed(flag='否'):
def cartel(f):
def doperunner():
print('贩毒小团伙内部开始计划...')
if flag == '是':
print('间谍已暴露')
f() #调用外部传入内部函数的逻辑,f的功能由传入的函数定义
print('贩毒小团伙内部开始行动...')
return doperunner
return cartel
# 定义要传入的函数
@is_exposed()
def spy():
print(f'我要把间谍注入贩毒集团下的分部')
print(f'间谍开始收集情报')
print(f'间谍回馈情报')
print(f'总部收到间谍情报,得知小团伙近期行动计划,开始布署')
# 第一次调用
spy()
print('我是分隔线'.center(30,'#'))
@is_exposed('是')
def spy():
print(f'我要把间谍注入贩毒集团下的分部')
print(f'间谍开始收集情报')
print(f'间谍回馈情报')
print(f'总部收到间谍情报,得知小团伙近期行动计划,开始布署')
# 第二次调用
spy()
猜你喜欢
- 2025-07-03 从零开始学python爬虫(七):selenium自动化测试框架的介绍
- 2025-07-03 在ubuntu环境下部署svn可视化管理工具iF.SVNAdmin详细教程
- 2025-07-03 Python ROS2 部署 兼容ROS1(ros publisher python)
- 2025-07-03 Jupyter MCP服务器部署实战:AI模型与Python环境无缝集成教程
- 2025-07-03 【Python大语言模型系列】阿里云人工智能平台部署ChatGLM2-6B
- 2025-07-03 干货 | 一步步部署 Flask 应用(flask部署到服务器)
- 2025-07-03 如何使用 PyTriton 在 Python 中部署 AI 模型
- 2025-07-03 如何将Python算法模型注册成Spark UDF函数实现全景模型部署
- 2025-07-03 简直不要太简单!用宝塔面板轻松部署 Python Web 应用
- 2025-07-03 Python项目源码加密部署方案(python的项目源码)
- 274℃Python短文,Python中的嵌套条件语句(六)
- 272℃python笔记:for循环嵌套。end=""的作用,图形打印
- 270℃PythonNet:实现Python与.Net代码相互调用!
- 265℃Python操作Sqlserver数据库(多库同时异步执行:增删改查)
- 265℃Python实现字符串小写转大写并写入文件
- 124℃原来2025是完美的平方年,一起探索六种平方的算吧
- 105℃Python 和 JavaScript 终于联姻了!PythonMonkey 要火?
- 103℃Ollama v0.4.5-v0.4.7 更新集合:Ollama Python 库改进、新模型支持
- 最近发表
-
- Python错误:IndentationError (缩进错误)
- 字符串对齐的常用方法(对字符串的常用处理方法)
- Python轻松实现markdown转网页,完美支持mermaid图表、latex公式
- Python循环语句(python循环语句分为哪两种)
- 编程小白学做题:Python 的经典编程题及详解,附代码和注释(六)
- Python入门到脱坑经典案—数字金字塔
- Python输出语句print()(python语句print(type(1j))的输出结果)
- Python入门到脱坑经典案例—九九乘法表
- Python格式化:让数据输出更优雅(Python格式化输出代码)
- 一节课的时间快速掌握Python基础知识
- 标签列表
-
- python中类 (31)
- python 迭代 (34)
- python 小写 (35)
- python怎么输出 (33)
- python 日志 (35)
- python语音 (31)
- python 工程师 (34)
- python3 安装 (31)
- python音乐 (31)
- 安卓 python (32)
- python 小游戏 (32)
- python 安卓 (31)
- python聚类 (34)
- python向量 (31)
- python大全 (31)
- python次方 (33)
- python桌面 (32)
- python总结 (34)
- python浏览器 (32)
- python 请求 (32)
- python 前端 (32)
- python验证码 (33)
- python 题目 (32)
- python 文件写 (33)
- python中的用法 (32)