Python函数总结
目录
一、函数的基础
1.函数的本质与价值
2.函数的定义与调用
3.参数类型详解
3.1 位置参数
3.2 关键字参数
3.3 默认参数
3.4 可变参数
4.返回值处理
5.函数作用域
二、函数的进阶
1.高阶函数
1.1 高阶函数的定义
1.2 匿名函数(lambda)
1.3 filter()函数
1.4 map()函数
1.5 zip()函数
1.6 reduce()函数
2. 递归函数
3. 函数当做参数
4. 函数当做返回值
5. 函数当做元素
5.1 当做字典中的元素
5.2 当做列表中的元素
三、函数的应用
1. 闭包
1.1 闭包的作用
1.2 闭包的构成条件
2. 装饰器
2.1 什么是装饰器
2.2 装饰器的作用
2.3 装饰器的应用场景
2.3.1 通用装饰器
2.3.2 使用装饰器传递参数
在 Python 编程世界中,函数是构建高效代码的基石。无论是处理简单的数值计算,还是开发复杂的大型应用,函数都扮演着不可或缺的角色。本文将系统梳理 Python 函数的核心知识,从基础语法到高级特性,帮你构建完整的函数知识体系。
一、函数的基础
1.函数的本质与价值
函数本质上是一段可重复执行的代码块,它通过封装特定逻辑实现代码复用。想象一下,如果没有函数,每次计算圆面积都要重复编写 π 乘以半径平方的公式,不仅效率低下,还会导致代码臃肿不堪。
函数的核心价值体现在三个方面:
(1)代码复用:一次定义,多次调用,减少重复编码
(2)逻辑模块化:将复杂问题拆解为独立功能单元,便于维护
(3)提高可读性:用有意义的函数名替代冗长代码,让程序更易理解
2.函数的定义与调用
基础语法结构
定义函数的基本语法如下:
def 函数名(参数列表):"""函数文档"""函数体return 返回值 # 可选
其中def是定义函数的关键字,函数名需遵循标识符命名规则(字母、数字、下划线组合,不能以数字开头)。
函数调用非常简单,只需使用函数名(参数)的形式:
def calculate_area(radius):"""计算圆的面积"""return 3.14159 * radius ** 2# 调用函数
area = calculate_area(5)
print(area) # 输出78.53975
值得注意的是,函数定义必须在调用之前,否则会抛出NameError。
3.参数类型详解
Python 函数的参数机制非常灵活,支持多种参数类型,合理使用能让函数更强大。
3.1 位置参数
最基础的参数类型,必须按顺序传递,数量需与定义一致:
def greet(name, message):print(f"{name}, {message}")greet("Alice", "good morning") # 正确调用
3.2 关键字参数
调用时指定参数名,可打乱顺序,增强代码可读性:
greet(message="good morning", name="Alice") # 与上例效果相同
3.3 默认参数
定义时指定默认值,调用时可省略该参数:
def greet(name, message="hello"):"""打招呼函数参数:name (str): 姓名message (str): 问候语,默认为'hello'"""print(f"{name}, {message}")# 使用默认参数调用
greet("Bob") # 输出: Bob, hello# 覆盖默认参数调用
greet("Bob", "welcome") # 输出: Bob, welcome
注意:默认参数必须放在位置参数后面,否则会报语法错误。
3.4 可变参数
处理不确定数量的参数,有两种形式:
(1)*args:接收任意数量的位置参数,形成元组
(2)**kwargs:接收任意数量的关键字参数,形成字典
def sum_numbers(*args):"""计算任意数量数字的和"""total = 0for num in args:total += numreturn total# 测试可变位置参数
print(sum_numbers(1, 2, 3)) # 输出: 6
print(sum_numbers(10, 20, 30, 40)) # 输出: 100def print_info(**kwargs):"""打印键值对信息"""for key, value in kwargs.items():print(f"{key}: {value}")# 测试可变关键字参数
print_info(name="Alice", age=30)
# 输出:
# name: Alice
# age: 30print_info(city="Beijing", country="China", population=21710000)
# 输出:
# city: Beijing
# country: China
# population: 21710000
4.返回值处理
函数通过return语句返回结果,具有以下特性:
(1)函数可返回任意类型的数据,包括基本类型、列表、字典甚至其他函数
(2)没有return语句的函数,默认返回None
(3)return会立即终止函数执行,其后的代码不会运行
(4)可返回多个值,实际以元组形式返回
def get_user_info():"""获取用户信息"""name = "Alice"age = 30return name, age # 隐式返回元组,等价于 return (name, age)# 自动解包返回值
user_name, user_age = get_user_info()
print(f"用户名: {user_name}, 年龄: {user_age}") # 输出: 用户名: Alice, 年龄: 30# 也可以直接接收整个元组
user_data = get_user_info()
print(f"完整数据: {user_data}") # 输出: 完整数据: ('Alice', 30)
5.函数作用域
变量的可见范围称为作用域,Python 中有四种作用域:
(1)局部作用域(Local):函数内部定义的变量,仅在函数内有效
(2)嵌套作用域(Enclosing):外层函数的变量,对嵌套的内层函数可见
(3)全局作用域(Global):模块级别的变量,整个模块均可访问
(4)内置作用域(Built-in):Python 内置的变量和函数(如print、len)
使用global关键字可在函数内修改全局变量,nonlocal关键字可修改嵌套作用域的变量:
def increment():"""计数器增加函数"""global count # 声明使用全局变量count += 1# 测试函数
increment()
print(count) # 输出: 1# 再次调用验证
increment()
print(count) # 输出: 2
二、函数的进阶
1.高阶函数
1.1 高阶函数的定义
(1)接收函数作为参数:可以接受一个或多个函数作为输入参数
(2)返回函数作为结果:将函数作为返回值输出
1.2 匿名函数(lambda)
用lambda关键字创建的简洁函数,仅能包含一个表达式:
add = lambda x, y: x + y
print(add(3, 5)) # 输出8# 常用于排序等场景
students = [("Alice", 20), ("Bob", 18), ("Charlie", 22)]
students.sort(key=lambda x: x[1]) # 按年龄排序
1.3 filter()函数
用于过滤序列,过滤掉不符合条件的元素,返回一个迭代器对象,接收两个参数,第一个为函数,第二个为序列,函数的作用是判断每个元素是否符合条件。
# 过滤出列表中的偶数
nums = [1, 2, 3, 4, 5, 6]
result = filter(lambda x: x % 2 == 0, nums)
print(list(result)) # 输出: [2, 4, 6]
1.4 map()函数
将传入的函数依次作用到序列的每个元素,并把结果作为新的迭代器返回,接收两个参数,第一个为函数,第二个为序列(可多个序列) 。
# 对列表中每个数求平方
nums = [1, 2, 3, 4]
result = map(lambda x: x ** 2, nums)
print(list(result)) # 输出: [1, 4, 9, 16]
1.5 zip()函数
用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的迭代器,若各个可迭代对象的元素个数不一致,则返回的迭代器长度与最短的可迭代对象相同。
list1 = [1, 2, 3]
list2 = ["a", "b", "c"]
result = zip(list1, list2)
print(list(result)) # 输出: [(1, 'a'), (2, 'b'), (3, 'c')]
1.6 reduce()函数
它会对参数序列中元素进行累积计算,接收两个参数,第一个为函数(该函数需接收两个参数,返回一个值 ),第二个为序列,依次将前一个计算结果和序列下一个元素传入函数进行计算 。
from functools import reduce
# 计算列表元素的累加和,等价于 1 + 2 + 3 + 4
nums = [1, 2, 3, 4]
result = reduce(lambda x, y: x + y, nums)
print(result) # 输出: 10
2. 递归函数
递归函数的作用:
(1)简化复杂问题:将复杂问题分解为相似的小问题,逻辑更清晰
(2)处理递归结构数据:特别适合处理树、图等递归结构的数据
(3)实现数学定义:许多数学定义本身就是递归的(如阶乘、斐波那契数列)
(4)简化代码:相比循环,某些问题用递归实现更简洁直观
# 计算列表求和
def sum_list(lst):# 基线条件:空列表的和为0if not lst:return 0# 递归条件:第一个元素 + 剩余元素的和return lst[0] + sum_list(lst[1:])print(sum_list([1, 2, 3, 4])) # 输出: 10
3. 函数当做参数
函数可像其他数据类型一样传递,这是函数式编程的基础:
def apply_func(func, x, y):return func(x, y)result = apply_func(lambda a, b: a * b, 4, 5)
print(result) # 输出20
4. 函数当做返回值
将函数作为返回值,可以在需要的时候才调用该 函数来计算结果,从而避免了不必要的计算,提高了程序的性能和效率。
# 定义一个返回函数的函数
def create_greeter(greeting):def greeter(name):return f"{greeting}, {name}!"return greeter# 获取返回的函数
say_hello = create_greeter("Hello")
say_hi = create_greeter("Hi")# 使用返回的函数
print(say_hello("Alice")) # 输出: Hello, Alice!
print(say_hi("Bob")) # 输出: Hi, Bob!
5. 函数当做元素
5.1 当做字典中的元素
# 创建函数字典
operation_dict = {'add': lambda x, y: x + y,'subtract': lambda x, y: x - y,'multiply': lambda x, y: x * y
}# 使用字典中的函数
print(operation_dict['add'](10, 5)) # 输出: 15
print(operation_dict['multiply'](10, 5)) # 输出: 50
5.2 当做列表中的元素
# 创建一个包含函数的列表
function_list = [lambda x: x ** 2, # 平方函数lambda x: x + 1, # 加1函数lambda x: x * 2 # 乘以2函数
]# 使用列表中的函数
number = 5
for func in function_list:number = func(number)print(number)# 输出:
# 25 (5的平方)
# 26 (25加1)
# 52 (26乘以2)
三、函数的应用
1. 闭包
1.1 闭包的作用
(1)在全局作用域对局部变量的间接访问
(2)可以形成装饰器
1.2 闭包的构成条件
闭包的构成条件三步走:1.有嵌套 2.有引用3.有返回
嵌套函数中,内层函数引用外层函数的变量,且外层函数返回内层函数:
def make_multiplier(factor):def multiplier(number):return number * factorreturn multiplierdouble = make_multiplier(2)
print(double(5)) # 输出10
2. 装饰器
2.1 什么是装饰器
在不改变现有函数源代码以及函数调⽤⽅式的前提下,实现给函数增加额外的功能。
2.2 装饰器的作用
装饰器的作用一般是:
(1)扩展功能:在不修改原函数代码的情况下添加新功能
(2)代码复用:将多个函数共用的功能封装成装饰器
(3)保持简洁:避免在每个函数中重复相同的代码
(4)分离关注点:将核心逻辑与附加功能分离
2.3 装饰器的应用场景
2.3.1 通用装饰器
# 定义一个简单的装饰器函数outer,它接收一个函数fun作为参数
def outer(fun):# 定义内部函数inner,它将替代原始函数def inner(*args, **kwargs):# 调用原始函数并保存结果res = fun(*args, **kwargs)# 返回原始函数的执行结果return res# 返回inner函数对象(注意不是调用它)return inner# 使用@outer装饰器语法糖装饰my_fun函数
# 等价于:my_fun = outer(my_fun)
@outer
def my_fun(*args, **kwargs):print('函数内容')# 调用被装饰后的函数
my_fun()
2.3.2 使用装饰器传递参数
# 定义一个带参数的装饰器工厂函数
# times参数指定函数需要重复执行的次数
def repeat(times):# 实际的装饰器函数,接收被装饰的函数作为参数def decorator(func):# 包装函数,用来替代原始函数def wrapper(*args, **kwargs):# 循环执行被装饰的函数for _ in range(times):# 保存最后一次调用的结果result = func(*args, **kwargs)# 返回最后一次调用的结果return result# 返回包装函数return wrapper# 返回装饰器函数return decorator# 使用装饰器,指定重复3次
@repeat(3) # 等价于 greet = repeat(3)(greet)
def greet(name):print(f"Hello, {name}!")# 调用被装饰后的函数
greet("Alice")