AI大模型入门-Python进阶-高阶函数
2026/7/22 5:18:08 网站建设 项目流程

视频链接:

https://space.bilibili.com/70431433?spm_id_from=333.1007.0.0

文章代码链接:

https://github.com/zyf-ngu/Qmatter

4高阶函数

内部函数-闭包

在 Python 中,内部函数(嵌套函数)可以直接访问外部函数的参数和变量,这种特性称为闭包(Closure)。闭包允许内部函数捕获并记住外部函数的环境,即使外部函数已经执行完毕。

闭包类似 “实例化” 的效果 —— 创建多个独立的 “函数实例”,它们拥有各自独立的状态,互不干扰。通过 “局部状态记忆” 替代全局变量,将状态封装在函数内部,避免全局变量易引发命名冲突(如多个模块定义count变量)。

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

def make_counter():

count = 0 # 外部函数的变量

def counter():

nonlocal count

count += 1

return count

# 返回内部函数(闭包)

return counter

# 创建计数器实例

counter1 = make_counter()

counter2 = make_counter()

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

print(counter1()) # 1

print(counter1()) # 2

print(counter2()) # 1

print(counter1()) # 3

print(counter2()) # 2

关键规则:

  1. 读取外部参数 / 变量:内部函数可以直接读取外部函数的参数和变量。
  2. 修改限制:默认情况下,内部函数不能直接修改外部函数的不可变类型变量(如 int、str、tuple),但可以修改可变类型变量(如 list、dict)。

强制修改:如果需要修改外部函数的不可变变量,可以使用nonlocal关键字声明。

以下是关于 Python 嵌套函数(闭包)的具体实例,展示了不同情况下内部函数对外部变量的访问和修改方式:

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

def outer_function(message):

# 外部函数的变量

outer_var = "外部变量"

def inner_function():

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

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

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

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

inner_function()

# 调用外部函数

outer_function("外部参数")

输出:

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

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

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

def outer_function():

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

outer_list = [1, 2, 3]

def inner_function():

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

outer_list.append(4)

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

inner_function()

return outer_list

# 调用外部函数

result = outer_function()

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

输出:

内部函数修改后的列表: [1, 2, 3, 4]

外部函数返回的列表: [1, 2, 3, 4]

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

def outer_function():

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

outer_num = 10

def inner_function():

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

nonlocal outer_num

outer_num = 20 # 现在可以修改了

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

inner_function()

return outer_num

# 调用外部函数

result = outer_function()

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

输出:

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

外部函数返回的数值: 20

装饰器函数

我们知道,函数是封装了特定功能的代码块,前面也介绍了函数参数的具体传递,不过参数均是简单的变量。如果我们想对函数的功能进行扩展应该怎么做呢?直接修改函数代码必然不是一个好选择,python提供了装饰器。

装饰器是Python中一个非常强大的功能,它允许我们修改或增强函数、方法或类的行为,而不需要改变其本身的代码。装饰器本质上是一个可调用对象(通常是一个函数),它接受一个函数作为参数,并返回一个新的函数。新函数包括2部分,核心部分是原函数的功能,第2部分就是新增的模式化的通用功能

其基本结构如下:

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

def decorator_function(func):

#2定义一个包装函数(wrapper),参数使用*args,**kwargs,以适应各种参数的原函数,这里参数和原函数是对应的

def wrapper(*args,**kwargs):

语句1#3.在原函数前后增加一些通用的功能语句,也可以使用上面传递进来的参数

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

语句2

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

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

# 6 使用方式,@+装饰器函数名,下面跟着接收函数的定义,之后正常调用接收函数

@decorator_function

def func:

pass

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

def log_decorator(func):

defwrapper(*args, **kwargs):

for num in args:#内部扩展函数的其它语句也可以使用
print('num:',num)
print(f"Before function {func.__name__} is called.")

result = func(*args, **kwargs)

print(f"After function {func.__name__} is called.")

return result

return wrapper

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

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

return a + b

result = add(3, 5)

print(result)

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

def require_role(role):

#外层接收装饰器参数

def decorator(original_func):

# 中间层接收函数

def wrapper(*args, **kwargs):

# 内层实现装饰逻辑

if role == "admin":

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

return original_func(*args, **kwargs)

else:

raise PermissionError("权限不足!")

return wrapper

return decorator

# 应用带参数的装饰器

@require_role("admin")

def delete_database():

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

@require_role("user")

def view_data():

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

# 测试

delete_database() # 成功执行

try:

view_data() # 触发异常

except PermissionError as e:

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

总结一下,装饰器函数本质上是一个函数,其主要功能和作用体现在以下几个方面:

1. 代码复用和模块化

装饰器可以将一些通用的功能(如日志记录、权限验证、性能测试等)封装起来,然后应用到多个不同的函数上,避免了代码的重复编写,提高了代码的复用性和可维护性。

2. 功能增强

在不修改原函数代码的前提下,为原函数添加额外的功能。这符合软件开发中的开闭原则,即对扩展开放,对修改关闭。

3. 分离关注点

将与核心业务逻辑无关的功能(如日志、权限控制等)从业务逻辑中分离出来,使代码结构更加清晰,便于维护和管理。

注意事项-

装饰器会改变被装饰函数的元信息(如函数名、文档字符串等),可以使用`functools.wraps`来保留这些信息。

- 装饰器在模块导入时就会执行,因此装饰器内部的代码会在导入时运行。

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

import functools

def my_decorator(func):

@functools.wraps(func)

def wrapper(*args, **kwargs):

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

return func(*args, **kwargs)

return wrapper

@my_decoratordef example():

print("Hello")

print(example.__name__) # 输出 'example' 而不是 'wrapper'

print(example.__doc__) # 输出 '示例函数的文档字符串' 而不是 '包装函数的文档字符串'```

匿名函数(Lambda 函数)

匿名函数(Lambda 函数)是一种不需要使用def关键字定义的函数,它使用lambda关键字创建。Lambda 函数是一个小型、匿名的函数,可以接受任意数量的参数,但只能有一个表达式

语法:

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

原理:
Lambda 函数在运行时创建返回一个函数对象。这个函数对象可以像普通函数一样被调用,参数在调用时传递进去,但它没有函数名(因此称为"匿名"函数)。

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

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

函数式编程:常与高阶函数(如 map(), filter(), reduce())配合使用

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

# 1. lambda基本用法

add= lambda x, y: x + y

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

# 2. 与普通函数对比

def add_def(x, y):

return x + y

# Lambda 版本更简洁

# 3. 在排序中使用

students = [("Alice", 90), ("Bob", 85), ("Charlie", 95)]# 按分数排序

sorted_students = sorted(students, key=lambda x: x[1])

print(sorted_students) # 输出: [('Bob', 85), ('Alice', 90), ('Charlie', 95)]

# 4. 立即调用 lambda 函数

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

print(result) # 输出: 30

高阶函数

高阶函数是指能够接收函数作为参数或将函数作为返回值的函数。在 Python 中,函数是一等对象(first-class objects),这意味着函数可以像其他对象一样被传递和操作。通过将函数作为参数或返回值,实现了更高层次的抽象和代码复用。

抽象通用模式:将通用操作模式抽象出来,具体行为通过函数参数定制

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

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

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

高阶函数、闭包和装饰器之间的关系可以概括为:装饰器是闭包的一种应用,而闭包又是高阶函数的一种形式。

高阶函数是指能够接收函数作为参数,或者将函数作为返回值的函数。

闭包是指在一个内部函数中,对外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包。闭包允许函数记住并访问其词法作用域中的变量,即使函数是在其作用域之外执行。

装饰器本质上是一个函数,它接收一个函数作为参数,并返回一个新的函数。装饰器通常用于在不修改原函数代码的情况下,为函数添加新的功能。

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

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

装饰器内部通常会定义一个闭包(内部函数),这个闭包会引用外部函数的参数(即被装饰的函数)以及外部作用域的变量。

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

def apply_operation(func, x, y):

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

return func(x, y)

# 使用不同的操作

result1 = apply_operation(lambda a, b: a + b, 5, 3)

result2 = apply_operation(lambda a, b: a * b, 5, 3)

print(result1, result2) # 输出: 8 15

#2. Python 内置高阶函数

from functools import reduce

numbers = [1, 2, 3, 4, 5]

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

squared = list(map(lambda x: x**2, numbers))

print(squared) # 输出: [1, 4, 9, 16, 25]

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

evens = list(filter(lambda x: x % 2 == 0, numbers))

print(evens) # 输出: [2, 4]

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

sum_all = reduce(lambda x, y: x + y, numbers)

print(sum_all) # 输出: 15

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

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

立即咨询