
目录1. 什么是函数2. 函数的定义2.1 基本语法2.2 带参数的函数2.3 带返回值的函数2.4 空函数占位3. 函数的调用4. 参数类型详解4.1 位置参数必须参数4.3 关键字参数4.4 可变长度参数4.5 参数组合顺序5. 返回值详解5.1 单个返回值5.2 多个返回值本质是返回元组5.3 return 语句省略时返回 None5.4 return 提前退出函数6. 作用域6.1 局部变量与全局变量6.2 nonlocal 关键字用于嵌套函数7. 函数也是对象8. 匿名函数lambda9. 递归函数10. 类型注解Type Hints11. 常见内置函数示例12.常见陷阱与最佳实践在编程中我们经常需要重复执行某段代码。如果每次都复制粘贴不仅代码冗长而且修改起来非常麻烦。函数就是解决这个问题的利器它将一段具有独立功能的代码打包成一个“积木块”需要时只需“调用”即可。1. 什么是函数函数是一段可重复使用的代码块它接收输入参数进行处理并可能返回输出返回值。函数可以帮你避免重复同样的逻辑只需写一次。模块化将复杂程序拆分成小功能块。易维护修改函数内部实现所有调用处自动生效。Python 内置了很多函数如print()、len()你也可以自定义函数。2. 函数的定义2.1 基本语法使用def关键字定义函数后面跟函数名、括号()和冒号:函数体缩进。def function_name(parameters):可选的文档字符串函数体代码return 返回值 # 可选egdef greet(): 打印欢迎信息 print(Hello, welcome to Python!) # 调用函数 greet()def greet():def是定义函数的关键字greet是函数名空括号表示该函数不接受任何参数冒号表示函数体开始。打印欢迎信息这是一个文档字符串docstring用三个双引号包围。它是对函数功能的说明可以通过help(greet)或greet.__doc__查看。虽然不是必需的但强烈建议添加。print(Hello, welcome to Python!)这是函数体缩进表示属于函数的一部分。当函数被调用时这一行代码会被执行。greet()调用函数执行函数体内的代码。2.2 带参数的函数def greet_person(name): 向指定的人打招呼 print(fHello, {name}!) greet_person(Alice) # Hello, Alice!def greet_person(name):定义了一个形参name它将在函数内部作为变量使用。print(fHello, {name}!)函数体内使用了name变量它的值由调用时传入。greet_person(Alice)调用时传入实参Alice它会被赋值给形参name因此函数体内输出Hello, Alice!。2.3 带返回值的函数使用return语句返回结果。def add(a, b): 返回两个数的和 result a b return result sum_val add(3, 5) # 返回 8 print(sum_val)代码解析def add(a, b):定义两个形参a和b。result a b计算两个参数的和赋值给局部变量result。return result将result的值返回给调用者。函数执行到return语句时会立即结束并将返回值传递给调用方。sum_val add(3, 5)调用add函数实参3和5分别传给a和b函数返回8然后赋值给变量sum_val。print(sum_val)输出8。2.4 空函数占位如果函数体还未实现可以用pass占位。def not_ready(): pass # 稍后实现代码解析def not_ready():定义函数。pass是一个空语句什么都不做。语法上需要一个语句但逻辑上还未实现用pass避免语法错误。3. 函数的调用调用函数就是使用函数名加上括号和实际参数。# 定义 def multiply(x, y): return x * y # 调用 result multiply(4, 5) print(result) # 20代码解析def multiply(x, y):定义乘法函数。return x * y返回两数乘积。result multiply(4, 5)调用函数实参4对应x5对应y返回值20存入result。print(result)输出20。调用时的细节函数名后面必须跟括号即使没有参数也要写()。实参会按照形参的位置一一对应位置参数。调用时传递的实参个数必须与形参个数匹配除非有默认参数。4. 参数类型详解4.1 位置参数必须参数最普通的形式调用时按顺序传递。def greet_with_default(name, greetingHello): print(f{greeting}, {name}!) greet_with_default(Alice) # Hello, Alice! greet_with_default(Bob, Hi) # Hi, Bob!代码解析greetingHello为greeting参数指定默认值Hello。调用时若不提供第二个参数则使用默认值。greet_with_default(Alice)只传一个参数greeting使用默认值Hello输出Hello, Alice!。greet_with_default(Bob, Hi)传入两个参数greeting被覆盖为Hi输出Hi, Bob!。注意默认参数必须放在非默认参数之后。# 错误写法 def wrong(a1, b): # SyntaxError pass陷阱默认参数的值只在函数定义时计算一次因此不能使用可变对象作为默认值如列表。# 不推荐 def add_item(item, lst[]): lst.append(item) return lst print(add_item(1)) # [1] print(add_item(2)) # [1, 2] ← 同一个列表被重复使用代码解析因为默认参数lst在函数定义时被创建一个空列表之后每次调用若不提供lst都会使用同一个列表对象导致累积。解决办法是使用None作为默认值然后在函数内部创建新列表。正确做法def add_item(item, lstNone): if lst is None: lst [] lst.append(item) return lst代码解析lstNone默认值设为不可变对象None。if lst is None: lst []每次调用时若未传入列表则新建一个空列表保证了独立性。4.3 关键字参数调用时通过形参名指定实参可以改变顺序。def describe_pet(name, species): print(f{name} is a {species}) describe_pet(speciescat, nameTom) # Tom is a cat代码解析describe_pet(speciescat, nameTom)显式指定每个参数的名字顺序可以与定义不同。这样调用时不会受位置影响增强了可读性。4.4 可变长度参数*args接收任意多个位置参数打包成元组。**kwargs接收任意多个关键字参数打包成字典。def sum_all(*args): return sum(args) print(sum_all(1, 2, 3, 4)) # 10代码解析*args收集所有传入的位置参数为一个元组这里args是(1,2,3,4)。sum(args)内置函数sum对元组求和返回10。def print_info(**kwargs): for key, value in kwargs.items(): print(f{key}: {value}) print_info(nameAlice, age30, cityParis)代码解析**kwargs收集所有传入的关键字参数为一个字典这里kwargs是{name:Alice,age:30,city:Paris}。遍历字典并打印。4.5 参数组合顺序在函数定义中参数的顺序必须是位置参数默认参数*args关键字参数仅限*之后**kwargsdef complex_func(a, b1, *args, c2, **kwargs): pass代码解析a是普通位置参数。b1是默认参数。*args接收多余的位置参数。c2是仅限关键字参数必须通过关键字传递。**kwargs接收多余的关键字参数。5. 返回值详解5.1 单个返回值def square(x): return x ** 2代码解析函数返回x的平方返回后调用方可以接收。5.2 多个返回值本质是返回元组def get_stats(numbers): return min(numbers), max(numbers), sum(numbers)/len(numbers) low, high, avg get_stats([1,2,3,4,5]) print(low, high, avg) # 1 5 3.0代码解析return min(...), max(...), avg(...)实际上返回了一个元组(min, max, avg)。调用方通过low, high, avg ...进行拆包分别接收三个值。5.3return语句省略时返回Nonedef do_nothing(): pass print(do_nothing()) # None代码解析函数没有显式return默认返回None。5.4return提前退出函数def is_positive(n): if n 0: return True return False代码解析如果n 0执行return True函数立即结束不会执行后面的return False。否则执行return False。这种写法可避免使用else。6. 作用域6.1 局部变量与全局变量在函数内部赋值的变量是局部变量只在函数内有效。在函数外部定义的变量是全局变量可在函数内读取但若要修改需用global关键字。x 10 # 全局变量 def func(): global x # 声明要修改全局变量 x 20 y 5 # 局部变量 func() print(x) # 20代码解析x 10全局变量。def func():内部global x告诉 Python 这里的x是全局变量而不是创建局部变量。x 20修改全局x的值为 20。y 5未声明global因此是局部变量函数外部无法访问。调用func()后全局x变为 20。注意避免过多使用global推荐通过参数传递和返回值来通信。6.2nonlocal关键字用于嵌套函数在内层函数中修改外层函数非全局的变量。def outer(): count 0 def inner(): nonlocal count count 1 return count return inner counter outer() print(counter()) # 1 print(counter()) # 2代码解析outer函数中定义了局部变量count和内层函数inner。inner中使用nonlocal count声明要修改的是外层函数outer的count变量而不是创建一个新的局部变量。count 1修改外层变量。outer返回inner函数对象形成一个闭包。每次调用counter()都会增加并返回count的值。7. 函数也是对象在 Python 中函数是一等公民可以赋值给变量、作为参数传递、作为返回值。def add(a, b): return a b my_func add # 赋值 print(my_func(3, 4)) # 7代码解析将函数add赋值给变量my_funcmy_func现在指向同一个函数对象可以像add一样调用。def apply(func, x, y): return func(x, y) print(apply(add, 5, 6)) # 11代码解析apply函数接收一个函数作为参数func然后在内部调用它。这体现了高阶函数的特性。8. 匿名函数lambdalambda表达式用于创建简单的、单表达式的匿名函数。square lambda x: x ** 2 print(square(5)) # 25代码解析lambda x: x ** 2定义了一个匿名函数等价于def square(x): return x**2。但lambda只能包含一个表达式不能包含语句。# 常用于 sort 的 key 参数 pairs [(1, one), (2, two), (3, three)] pairs.sort(keylambda pair: pair[1]) # 按字符串排序代码解析sort的key参数接收一个函数用于从每个元素中提取比较键。这里用lambda取每个元组的第二个元素字符串作为排序依据。限制lambda 只能有一个表达式不能包含语句如print、return等。9. 递归函数函数调用自身称为递归。需要明确的终止条件。def factorial(n): if n 1: return 1 return n * factorial(n - 1) print(factorial(5)) # 120代码解析if n 1: return 1递归的终止条件防止无限递归。return n * factorial(n-1)递归调用每次减少n的值。调用过程factorial(5)→5 * factorial(4)→5 * 4 * factorial(3)→ ... →5 * 4 * 3 * 2 * 1。注意Python 递归深度有限制默认约 1000深层递归建议改用循环。10. 类型注解Type HintsPython 3.5 支持类型注解提高代码可读性不强制检查。def greet(name: str) - str: return fHello, {name}代码解析name: str表示参数name应为字符串类型。- str表示返回值应为字符串类型。这些注解只是提示不会在运行时检查类型错误。可以用mypy工具进行静态类型检查。11. 常见内置函数示例print()输出len()返回长度type()返回类型input()读取用户输入range()生成整数序列sum()、max()、min()等这些内置函数无需定义直接使用。12.常见陷阱与最佳实践陷阱说明解决方案使用可变对象作为默认参数函数多次调用共享同一对象使用None并在函数内创建新对象在函数内修改全局变量未声明会创建同名局部变量使用global或通过参数/返回值传递混淆位置参数和关键字参数调用时顺序错误明确指定关键字参数名递归深度过大导致栈溢出递归超过系统限制改用循环或增加sys.setrecursionlimit忘记return导致返回None预期有返回值但实际为None检查函数所有分支是否都有returnlambda内使用复杂逻辑无法使用语句代码难读改用普通函数感谢你的观看期待我们下次再见