【Python基础入门】第五课 : 函数进阶、作用域、参数详解与Lambda表达式

张开发
2026/5/4 16:30:56 15 分钟阅读

分享文章

【Python基础入门】第五课 : 函数进阶、作用域、参数详解与Lambda表达式
大家好欢迎来到Python基础第五课在前几节课中我们已经学习了函数的基本概念知道了如何定义和调用函数。今天我们将深入函数的内部探索变量的作用域、函数的参数传递机制以及lambda表达式这个简洁强大的工具。学会这些你就能写出更加灵活、高效的代码一、变量的作用域作用域Scope简单来说就是变量能够被访问的范围。理解作用域能帮你避免很多莫名其妙的错误。1.1 全局变量 vs 局部变量全局变量定义在函数外部的变量在当前文件的任何地方都可以访问。局部变量定义在函数内部或作为形参的变量只能在函数内部使用。python# 全局变量 name 乔峰 def func1(): # 局部变量 age 38 print(f全局变量: {name}) # 可以访问全局变量 print(f局部变量: {age}) # 可以访问局部变量 func1() print(f全局变量: {name}) # 可以访问 # print(age) # 报错无法在外部访问局部变量记忆口诀全局变量“活”在全文件。局部变量“死”在函数内。1.2 global关键字在函数内修改全局变量如果你需要在函数内部修改全局变量的值必须先用global声明。pythonnum 10 def func(): global num # 声明num是全局变量 num 20 # 现在修改的是全局变量 func() print(num) # 输出 20如果不加 global 会怎样pythonnum 10 def func(): num 20 # 这是在创建一个新的局部变量不会影响全局变量 print(num) # 输出 20局部变量 func() print(num) # 输出 10全局变量没变使用原则除非确实需要否则尽量避免在函数内修改全局变量因为这会增加代码的理解难度。更好的做法是把数据作为参数传入把结果作为返回值传出。二、可变与不可变类型这是Python中一个非常重要的概念也是很多初学者容易踩的坑。2.1 如何区分可变与不可变看修改变量值后它的内存地址是否改变不可变类型修改后地址改变 → int、float、bool、str、tuple可变类型修改后地址不变 → list、set、dict使用id()函数可以查看变量在内存中的地址。python# 不可变类型int a 10 print(id(a)) # 假设是 140704877456088 a 20 print(id(a)) # 变成了另一个地址 140704877456408 # 可变类型list list1 [10, 20, 30] print(id(list1)) # 假设是 2798866600256 list1[1] 200 print(id(list1)) # 地址不变 27988666002562.2 这对函数参数意味着什么形参是不可变类型→ 形参的改变不影响实参值传递形参是可变类型→ 形参的改变直接影响实参引用传递python# 场景1形参是不可变类型int num 10 def change(num): num 20 # 形参重新赋值不影响外面的num change(num) print(num) # 仍然是 10 # 场景2形参是可变类型list num_list [10, 20, 30] def change(num_list): num_list[1] 200 # 修改列表元素影响外面的列表 change(num_list) print(num_list) # [10, 200, 30]理解要点不可变类型传递的是“值”函数内部修改不会影响外部。可变类型传递的是“引用”函数内部修改会影响外部。三、函数的参数详解Python的参数传递非常灵活我们来逐一拆解。3.1 实参的传递方式位置参数实参的顺序和形参必须一一对应。pythondef user_info(name, age, address): print(f我叫:{name}, 年龄:{age}, 地址:{address}) user_info(张三, 18, 北京) # 顺序必须一致关键字参数实参以“键值”的形式传递顺序可以随意。pythonuser_info(address上海, name李四, age19)混合使用位置参数必须在关键字参数之前。pythonuser_info(李白, address唐朝, age100) # 正确 # user_info(address唐朝, 李白, age100) # 错误位置参数不能放后面3.2 形参的定义方式缺省参数默认参数给形参设置一个默认值调用时如果不传就使用默认值。pythondef user_info(name, age, address北京): print(f我叫:{name}, 年龄:{age}, 地址:{address}) user_info(张三, 18) # 地址用默认值“北京” user_info(张三, 18, 上海) # 地址用传入的“上海”注意缺省参数必须放在普通参数后面不定长参数前面。不定长参数可变参数有时候我们不知道调用者会传入多少个参数这时可以用不定长参数。*args接收任意个位置参数打包成元组。pythondef fun01(*args): print(args) # (1, 10, False, abc) print(type(args)) # class tuple fun01(1, 10, False, abc)**kwargs接收任意个关键字参数打包成字典。pythondef fun02(**kwargs): print(kwargs) # {name: 张三, age: 18, address: 北京} print(type(kwargs)) # class dict fun02(name张三, age18, address北京)完全体函数把普通参数、缺省参数、不定长参数放在一起pythondef fun03(name, age, address北京, *args, **kwargs): print(f我叫:{name}, 年龄:{age}, 地址:{address}) print(fargs: {args}) # 额外的位置参数 print(fkwargs: {kwargs}) # 额外的关键字参数 fun03(乔峰, 38, 上海, 10, 20, 30, aa11, bb22, cc降龙十八掌)输出text我叫:乔峰, 年龄:38, 地址:上海 args: (10, 20, 30) kwargs: {aa: 11, bb: 22, cc: 降龙十八掌}3.3 实战任意个整数求和pythondef get_sum(*args): return sum(args) # sum() 是Python内置求和函数 print(get_sum()) # 0 print(get_sum(10, 20)) # 30 print(get_sum(1, 2, 3, 4, 5)) # 15如果需要同时处理位置参数和关键字参数pythondef get_sum(*args, **kwargs): return sum(args) sum(kwargs.values()) result get_sum(1, 2, 3, a10, b20, c30) print(result) # 66四、lambda表达式匿名函数有些函数非常简单只做一件事只有一行代码。我们不想专门用def定义一个函数这时可以用lambda表达式匿名函数。4.1 lambda的基本格式pythonlambda 形参列表 : 表达式等价于pythondef 函数名(形参列表): return 表达式4.2 案例对比无参lambdapythondef func01(): return 100 my_lambda1 lambda: 100 print(my_lambda1()) # 100有参lambdapythondef func02(a, b): return a b my_lambda2 lambda a, b: a b print(my_lambda2(11, 22)) # 33带默认参数的lambdapythondef func03(a, b, c100): return a b c my_lambda3 lambda a, b, c100: a b c print(my_lambda3(11, 22)) # 133带if判断的lambdapythondef func04(a): return True if a % 2 0 else False my_lambda4 lambda a: True if a % 2 0 else False print(my_lambda4(11)) # False print(my_lambda4(12)) # True4.3 lambda的应用场景lambda最常见的用途是作为函数的参数比如sort()的key参数。案例1对列表嵌套字典进行排序pythonstudents [ {name: Tom, age: 20}, {name: Rose, age: 19}, {name: Jack, age: 22} ] # 按 name 排序 students.sort(keylambda x: x[name]) print(students) # [{name: Jack, age: 22}, {name: Rose, age: 19}, {name: Tom, age: 20}] # 按 age 排序 students.sort(keylambda x: x[age]) print(students) # [{name: Rose, age: 19}, {name: Tom, age: 20}, {name: Jack, age: 22}]案例2模拟计算器定义一个函数接收两个数和一条计算规则lambda返回计算结果。pythondef my_calculate(a, b, rule): 模拟计算器按规则计算结果 return rule(a, b) # 加法 print(my_calculate(10, 3, lambda a, b: a b)) # 13 # 减法 print(my_calculate(10, 3, lambda a, b: a - b)) # 7 # 乘法 print(my_calculate(10, 3, lambda a, b: a * b)) # 30 # 除法 print(my_calculate(10, 3, lambda a, b: a / b)) # 3.333... # 取最大值 print(my_calculate(10, 3, lambda a, b: a if a b else b)) # 10这样写的好处是my_calculate函数本身不需要知道具体做什么计算计算规则由调用者灵活传入。这就是策略模式的简单体现。五、总结与作业今天我们学习了变量的作用域全局变量和局部变量以及用global修改全局变量。可变与不可变类型int、str、tuple 不可变list、set、dict 可变。参数传递机制位置参数、关键字参数、缺省参数、不定长参数*args和**kwargs。lambda表达式匿名函数的定义与应用特别是在排序和灵活计算场景中的使用。函数是Python编程的核心掌握这些进阶知识你就能写出更简洁、更灵活、更专业的代码。课后作业写一个函数create_counter()返回一个内部函数每次调用内部函数时计数加1使用nonlocal或全局变量实现。用*args写一个函数find_max返回传入的任意个整数中的最大值不能使用内置max。用**kwargs写一个函数print_info接收任意个关键字参数按格式打印每个键值对。有一个列表[(apple, 5), (banana, 2), (cherry, 8)]请用sort()结合 lambda 按第二个元素排序。用 lambda 表达式定义一个函数is_palindrome判断一个字符串是否是回文正反读一样如 aba 返回 Trueabc 返回 False。欢迎在评论区分享你的代码或疑问 预告下一节课我们将学习模块和包让Python代码真正走向工程化

更多文章