AI大模型入门-Python进阶-高阶函数

AI大模型入门-Python进阶-高阶函数 视频链接https://space.bilibili.com/70431433?spm_id_from333.1007.0.0文章代码链接https://github.com/zyf-ngu/Qmatter4高阶函数内部函数-闭包在 Python 中内部函数嵌套函数可以直接访问外部函数的参数和变量这种特性称为闭包Closure。闭包允许内部函数捕获并记住外部函数的环境即使外部函数已经执行完毕。闭包类似 “实例化” 的效果 —— 创建多个独立的 “函数实例”它们拥有各自独立的状态互不干扰。通过 “局部状态记忆” 替代全局变量将状态封装在函数内部避免全局变量易引发命名冲突如多个模块定义count变量。闭包的典型应用记住外部环境def make_counter():count 0 # 外部函数的变量def counter():nonlocal countcount 1return count# 返回内部函数闭包return counter# 创建计数器实例counter1 make_counter()counter2 make_counter()# 调用闭包每个实例会记住自己的count状态print(counter1()) # 1print(counter1()) # 2print(counter2()) # 1print(counter1()) # 3print(counter2()) # 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/dictdef 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修改外部不可变类型变量需用 nonlocaldef outer_function():# 外部函数的不可变类型变量整数outer_num 10def inner_function():#声明需要修改外部不可变变量nonlocal outer_numouter_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.在原函数前后增加一些通用的功能语句也可以使用上面传递进来的参数resultfunc(*args,**kwargs)#4.调用原函数语句2return result#5原函数有返回值则返回值包装函数结束return wrapper#最后返回扩展函数装饰器函数结束# 6 使用方式装饰器函数名下面跟着接收函数的定义之后正常调用接收函数decorator_functiondef func:pass举个例子在调用原函数前后添加了额外日志记录的功能。def log_decorator(func):defwrapper(*args, **kwargs):for num in args:#内部扩展函数的其它语句也可以使用print(num:,num)print(fBefore function {func.__name__} is called.)result func(*args, **kwargs)print(fAfter function {func.__name__} is called.)return resultreturn wrapperlog_decorator# 接收函数为参数的函数名前面加符号即为装饰器。def add(a, b):#原函数定义在下方return a bresult 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 wrapperreturn 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 functoolsdef my_decorator(func):functools.wraps(func)def wrapper(*args, **kwargs):print(装饰器中...)return func(*args, **kwargs)return wrappermy_decoratordef example():print(Hello)print(example.__name__) # 输出 example 而不是 wrapperprint(example.__doc__) # 输出 示例函数的文档字符串 而不是 包装函数的文档字符串匿名函数Lambda 函数匿名函数Lambda 函数是一种不需要使用def关键字定义的函数它使用lambda关键字创建。Lambda 函数是一个小型、匿名的函数可以接受任意数量的参数但只能有一个表达式。语法func可选函数对象lambdaarguments: expression原理Lambda 函数在运行时创建返回一个函数对象。这个函数对象可以像普通函数一样被调用参数在调用时传递进去但它没有函数名因此称为匿名函数。简洁性对于简单的操作使用 lambda 函数比定义完整函数更简洁一次性使用适用于只需要使用一次的小型函数函数式编程常与高阶函数如 map(), filter(), reduce()配合使用回调函数作为参数传递给其他函数# 1. lambda基本用法add lambda x, y: x yprint(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, keylambda 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 reducenumbers [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