AI大模型入门1.7-Python进阶-高阶函数
2026/8/29 5:16:32 网站建设 项目流程

视频链接:文章代码链接:4高阶函数内部函数-闭包

在其中, 内函数(嵌套而成的函数)能够直接去访问外函数的参数以及变量, 这般特性被称作闭包()。闭包许可内函数捕获并且记住外函数的环境, 哪怕外函数已然执行完毕。

闭包有着类似于 “实例化” 的那种效果, 它能够去创建多个彼此独立隔离的 “函数实例”, 而每一个这样的 “函数实例” 呢, 又都有着各自单独的、互不侵扰的状态。它借助 “局部状态记忆” 来替换全局变量, 把状态给封装到函数内部, 以此避免因多个模块分别定义count变量等, 而致使全局变量容易引发的命名冲突。

闭包的典型应用(记住外部环境)

def ():

count = 0 # 外部函数的变量

def ():

count

count += 1

count

# 返回内部函数(闭包)

# 创建计数器实例

= ()

= ()

# 调用闭包,每个实例会记住自己的count状态

print(()) # 1

print(()) # 2

print(()) # 1

print(()) # 3

print(()) # 2

关键规则:

提取外部参数以及变量, 内部函数能够直接获取外部函数的参数与变量, 存在修改限制, 在默认状况下, 内部函数无法直接改变外部函数的不可变类型变量, 像 int、str、tuple这样的, 不过能够改变可变类型变量, 比如 list、dict。

如若存在修改外部函数之中不可变变量的需求, 那么能够借助关键字予以声明。

以下是有关, 嵌套函数也即闭包的具体实例, 呈现了不同情形下, 内部函数对外部变量的访问途径以及修改方式。

实例 1:内部函数读取外部变量

def ():

# 外部函数的变量

= "外部变量"

def ():

# 内部函数读取外部变量和参数

print(f"内部函数访问外部参数: {}")

print(f"内部函数访问外部变量: {}")

# 调用内部函数,一般用于多线程处理

()

# 调用外部函数

("外部参数")

输出:

内部函数访问外部参数: 外部参数

内部函数访问外部变量: 外部变量

实例 2:修改外部可变类型变量(list/dict)

def ():

# 外部函数的可变类型变量(列表)

=

def ():

# 直接修改外部可变类型变量(无需特殊声明)

.(4)

print(f"内部函数修改后的列表: {}")

()

# 调用外部函数

= ()

print(f"外部函数返回的列表: {}")

输出:

内部函数修改后的列表:

1, 2, 3, 4

外部函数返回的列表:

1, 2, 3, 4

实例 3:修改外部不可变类型变量(需用 )

def ():

# 外部函数的不可变类型变量(整数)

= 10

def ():

# 声明需要修改外部不可变变量

= 20 # 现在可以修改了

print(f"内部函数修改后的数值: {}")

()

# 调用外部函数

= ()

print(f"外部函数返回的数值: {}")

输出:

内部函数修改后的数值: 20

外部函数返回的数值: 20

装饰器函数

我们清楚, 函数乃是封装了特定功能的代码块, 此前也讲述了函数参数的具体传递情形, 然而参数全都是简单的变量。要是我们想要对函数的功能予以扩展该如何去做呢? 直接去修改函数代码肯定不是一个好的选择, 故提供了装饰器。

装饰器是一项极具潜力的功能, 它能让我们将函数、方法或者类的操作予以调整补充, 却不用去变更其原本代码。它本质上属于可调用物品, 一般为某个函数, 它会把某函数当作参数收纳, 还会回馈一个全新的函数。全新函数涵盖两部分, 关键部分是原函数的效能, 另一部分是新增的有固定模式的普遍效能。

其基本结构如下:

#1 定义一个接收函数为参数的装饰器函数

def (func):

定义一个包装函数, 其参数采用*args以及**, 以此来适配各种参数的原函数, 在此处参数与原函数是相互对应的。

def (*args,**):

步骤3, 于原函数之前以及之后, 增添一些具备通用性的功能语句, 并且能够运用上面传递进来的参数, 使之得以使用。

=func(*args,**)#4.调用原函数

语句2

#5原函数有返回值则返回值,包装函数结束

#最后返回扩展函数,装饰器函数结束

# 6 使用方式, 先使用 @ 加上装饰器函数名, 接着下面跟着接收函数的定义, 随后正常调用接收函数。

@

def func:

pass

举个例子,在调用原函数前后添加了额外日志记录的功能。

def (func):

def (*args, **):

对于在参数之中的编号, #内部扩展函数的其它语句另外也能够加以使用。

print('num:',num)

print(f" {func.} is .")

= func(*args, **)

print(f"After {func.} is .")

@ # 接收函数为参数的函数名前面加@符号即为装饰器。

def add(a, b): #原函数定义在下方

a + b

= add(3, 5)

print()

# 带参数的装饰器需要三层嵌套

def (role):

# 外层接收装饰器参数

def ():

# 中间层接收函数

def (*args, **):

# 内层实现装饰逻辑

if role == "admin":

print("管理员权限验证通过")

(*args, **)

else:

raise ("权限不足!")

# 应用带参数的装饰器

@("admin")

def ():

print("数据库已删除!")

@("user")

def ():

print("显示数据...")

# 测试

() # 成功执行

try:

() # 触发异常

as e:

print(f"错误: {e}")

概括来讲, 装饰器函数从本质上而言是一个函数, 它的主要功能以及作用呈现于以下几个方面。

1. 代码复用和模块化

有些通用功能, 像日志记录、权限验证、性能测试等,能被装饰器封装起来, 之后应用到多个不一样的函数上, 如此避免了代码的重复编写, 进而提高了代码的复用性与可维护性。

2. 功能增强

前提是不修改原函数代码, 在此基础上为原函数添加额外功能, 这与软件开发里的开闭原则相契合, 也就是对扩展予以开放, 对修改加以关闭。

3. 分离关注点

去除掉和处于中心位置的业务逻辑没有关联的功能, 像是对日志进行记录的功能, 以及针对权限实施控制的功能等等, 将它们从业务逻辑里面抽离出来, 以此让代码的结构变得更为清晰, 更有利于开展维护工作以及进行管理。

注意事项-

当装饰器作用于函数时从而改变被装饰函数的元信息, 这里所说的元信息包含函数名、文档字符串等内容, 不过存在一种方式采用`.wraps`来将这些信息予以保留。

装饰器于模块导入之际便会去执行, 所以, 装饰器内部的那些代码会在导入这个行为发生的时候得以运行。

使用.wraps保留原始函数的元信息,

def (func):

@.wraps(func)

def (*args, **):

print("装饰器中...")

func(*args, **)

@ ():

print("Hello")

打印(点), 输出的是两个单引号中间为空字符的内容, 而非同样是两个单引号中间为空字符的内容。

print(.), 输出, ‘示例函数的文档字符串’, 而不是, ‘包装函数的文档字符串’, ```。

匿名函数( 函数)

一种函数, 它被称作匿名函数, 无需使用def关键字去定义它, 而是借助特定关键字予以创建, 它是小型的、匿名那种函数, 能够接纳任意数量的参数, 然而却仅仅可有一个表达式。

语法:

func(可选,函数对象)= :

原理:

函数于运行之际创建, 会返回一个函数对象, 此函数对象能够如同普通函数那般被调用, 参数于调用之时传递进去, 然而它不存在函数名(所以称其为“匿名”函数)。

简洁性:对于简单的操作,使用 函数比定义完整函数更简洁

一次性使用:适用于只需要使用一次的小型函数

函数式编程, 常常会跟高阶函数配合运用, 像map()函数, 以及另外两个未明确写出的函数。

回调函数:作为参数传递给其他函数

# 1. 基本用法

add = x, y: x + y

print(add(5, 3)) # 输出: 8

# 2. 与普通函数对比

def (x, y):

x + y

# 版本更简洁

# 3. 在排序中使用

=

具有数值90的名为Alice的元素, 具有数值85的名为Bob的元素 , 具有数值95的空元素。

# 按分数排序

= (, key= x: x)

print() # 输出:

包含这样几个元素, 分别是, 名为“Bob”且对应数值为85的, 名为“Alice”且对应数值为90的, 还有名为空字符串且对应数值为95的。

# 4. 立即调用 函数

= ( x, y: x * y)(5, 6)

print() # 输出: 30

高阶函数

高阶函数是这样一种函数, 它能够接收函数当作参数, 或者将函数作为返回值。在特定环境里, 函数属于一等对象, 这有着特别的意义, 也就是函数能够如同其他对象那般被传递以及操作。借助把函数作为参数或者返回值这种方式, 达成了更高层面的抽象以及代码复用。

抽象出通用操作模式的那种模式, 具体行为依据函数的参数来进行定做设计。

代码复用:减少重复代码,提高代码的可维护性

函数组合:通过组合简单函数构建复杂功能

延迟执行:可以创建并返回函数,在需要时执行

闭包属于高阶函数的一种形式, 装饰器是闭包的一种应用, 高阶函数、闭包和装饰器之间的关系可如此概括。

是指这样一种函数, 它能够把函数当作参数来接收, 或者把函数当作返回值来输出, 这种函数被称作高阶函数。

包含这样一种情况, 就是在一个内部函数里, 存在对外部作用域但并非全局作用域的变量进行引用的行为, 在此情形下, 之后这个内部函数就会被认定为是闭包。闭包具备这样的功能, 它能够让函数记住并且访问其词法作用域当中的变量, 哪怕该函数是在其作用域以外去执行。

存在这样一种事物, 它被称作装饰器, 从本质上来说, 它属于一个函数, 这个函数会去接收另外一个函数当作参数, 之后返回一个全新的函数。通常情况下, 装饰器是被用于在不改变原函数代码的情形下, 给函数增添新的功能的。

装饰器是利用闭包和高阶函数的特性来实现的。

装饰器是一个高阶函数,因为它接收函数作为参数并返回函数。

装饰器的内部, 一般而言会去定义一个闭包, 所谓闭包也就是内部函数, 这个闭包呢, 会去引用外部函数的参数, 而这里的外部函数参数就是被装饰的那个函数, 并且它还会引用外部作用域所存在的变量, 这些变量也是属于外部作用域的。

# 1. 接收函数作为参数的高阶函数(函数作为参数)

def (func, x, y):

"""应用给定的操作到两个参数上"""

func(x, y)

# 使用不同的操作

= ( a, b: a + b, 5, 3)

= ( a, b: a * b, 5, 3)

print(, ) # 输出: 8 15

# 2. 内置高阶函数

from

=

1, 2, 3, 4, 5

# map() - 对每个元素应用函数

= list(map( x: x**2, ))

print() # 输出:

1, 4, 9, 16, 25

# () - 过滤满足条件的元素

print(evens) # 输出:

# () - 累积计算序列中的元素

= ( x, y: x + y, )

print() # 输出: 15

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询