【Python】Python 函数基本介绍(详细版)
Python 函数基本介绍(详细版)
文章目录
- Python 函数基本介绍(详细版)
- 前言
- 一、函数的创建
- 1.1 函数名的命名规则
- 1.2 函数的创建
- 1.3 函数的调用
- 二、函数的参数
- 2.1 形参和实参
- 2.2 位置参数
- 2.3 关键字参数
- 2.4 默认参数
- 2.5 不定长参数
- 2.6 参数组合使用
- 三、函数的返回值
- 四、匿名函数
- 五、函数的作用域
- 六、嵌套函数
- 七、闭包
- 八、递归函数
- 总结
前言
函数是 Python 编程的核心构建块,它将特定功能的代码封装成独立单元,不仅能减少重复代码,还能让程序结构更清晰、易于维护。深入理解函数的各项特性,是编写高质量 Python 代码的基础。
一、函数的创建
函数创建的核心是用def关键字定义一个可复用的代码块,其完整结构包含函数名、参数列表、文档字符串、函数体和返回值,每个部分都有明确的作用。
1.1 函数名的命名规则
函数名需遵循 Python 标识符命名规范:
- 只能包含字母、数字和下划线
- 不能以数字开头
- 不能使用 Python 关键字(如def、if等)
- 建议使用小写字母,多个单词用下划线连接(蛇形命名法),如calculate_average
1.2 函数的创建
创建函数使用def关键字,基本语法为:
def 函数名(参数):函数体return 返回值
例如,创建一个计算两数之和的函数:
def add(a, b):result = a + breturn result
这里的add是函数名,a和b是参数,函数体是计算两数之和并将结果赋给result,最后通过return返回result。
1.3 函数的调用
调用函数只需使用 “函数名 (参数)” 的形式。以上面的add函数为例:
sum_result = add(3, 5)
print(sum_result) # 输出:8
当调用add(3, 5)时,函数内部的a被赋值为 3,b被赋值为 5,经过计算后返回 8,然后将 8 赋给sum_result并打印出来。
二、函数的参数
函数的参数是函数与外部交互的桥梁,根据传递和定义方式的不同,可分为多种类型。其中,形参和实参是参数的基本概念。
2.1 形参和实参
形参(形式参数):在定义函数时,括号中列出的参数称为形参,它们只是函数定义时用来接收外部传入数据的 “占位符”,没有具体的值。
例如在def add(a, b):中,a和b就是形参。
实参(实际参数):在调用函数时,括号中传入的具体数据称为实参,它们会被赋值给对应的形参。
例如在add(3, 5)中,3和5就是实参,分别赋值给形参a和b。
形参和实参的关系是:实参是形参的具体值,在函数调用时,实参的值会传递给形参,供函数体使用。
2.2 位置参数
位置参数是最常见的参数类型,参数按照位置顺序传递,实参与形参必须一一对应,数量也必须一致。如add(3,5)中,3 传给a,5 传给b。如果参数数量不匹配,会报错,例如add(3)会提示缺少一个位置参数。
2.3 关键字参数
调用时指定参数名(形参名),可改变参数顺序,使代码更具可读性。例如:
sum_result = add(b=5, a=3)
print(sum_result) # 输出:8
这里明确指定b为 5,a为 3,虽然顺序与函数定义时不同,但仍能正确计算结果。使用关键字参数时,关键字必须是函数定义时的形参名,否则会报错。
2.4 默认参数
定义函数时给形参设置默认值,调用时可省略该参数,若不省略则使用传递的实参值。示例:
def greet(name, greeting="Hello"):print(f"{greeting}, {name}!")
greet("Alice") # 输出:Hello, Alice!
greet("Bob", "Hi") # 输出:Hi, Bob!
在greet函数中,greeting是设置了默认值 “Hello” 的形参,当调用greet(“Alice”)时,没有传递对应greeting的实参,就使用默认值;调用greet(“Bob”, “Hi”)时,传递了实参 “Hi”,则使用该值。需要注意的是,默认参数必须放在位置参数之后,否则会报错,例如def greet(greeting=“Hello”, name):是错误的。
2.5 不定长参数
当不确定需要传递多少个实参时,可以使用不定长参数,它们能接收任意数量的实参。
*args:接收任意数量的位置实参,以元组形式存储,args是约定俗成的名称,也可以使用其他名称,但建议使用args。
def sum_numbers(*args):total = 0for num in args:total += numreturn total
print(sum_numbers(1, 2, 3)) # 输出:6
print(sum_numbers(4, 5, 6, 7)) # 输出:22
在sum_numbers函数中,*args接收了传递的所有位置实参,然后通过循环将它们相加。
**kwargs:接收任意数量的关键字实参,以字典形式存储,其中键是参数名(形参名),值是参数值(实参值),kwargs是约定俗成的名称,也可使用其他名称,建议使用kwargs。
def print_info(** kwargs):for key, value in kwargs.items():print(f"{key}: {value}")
print_info(name="Alice", age=20, gender="female")
# 输出:
# name: Alice
# age: 20
# gender: female
这里**kwargs接收了name、age、gender三个关键字实参,并以字典的形式遍历输出。
2.6 参数组合使用
在定义函数时,多种参数可以组合使用,但需要遵循一定的顺序:位置参数在前,然后是默认参数,接着是*args,最后是**kwargs。例如:
def func(a, b, c=0, *args, **kwargs):print(f"a={a}, b={b}, c={c}")print("args:", args)print("kwargs:", kwargs)
func(1, 2, 3, 4, 5, name="test", age=10)
# 输出:
# a=1, b=2, c=3
# args: (4, 5)
# kwargs: {'name': 'test', 'age': 10}
三、函数的返回值
函数的返回值是函数执行完成后给出的结果,通过return语句实现。
用return返回结果,函数执行到return后停止,后续的代码不会执行。
def check_number(num):if num > 0:return "正数"print("该数不是正数")
print(check_number(5)) # 输出:正数
print(check_number(-3)) # 输出:该数不是正数 然后输出None
当num为 5 时,函数执行到return "正数"就停止,不会执行后面的打印语句;当num为 - 3 时,不满足if条件,会执行打印语句,然后函数默认返回None。
可返回多个值,以元组形式接收,也可分别接收。
def get_name_and_age():return "Alice", 20
# 以元组形式接收
info = get_name_and_age()
print(info) # 输出:('Alice', 20)
# 分别接收
name, age = get_name_and_age()
print(name, age) # 输出:Alice 20
四、匿名函数
用lambda创建,语法:lambda 参数: 表达式,适合实现简单的功能,返回值是表达式的结果。
add = lambda a, b: a + b
print(add(3, 5)) # 输出:8
# 结合内置函数使用
numbers = [(1, 3), (4, 1), (2, 5)]
# 按元组中第二个元素排序
numbers.sort(key=lambda x: x[1])
print(numbers) # 输出:[(4, 1), (1, 3), (2, 5)]
匿名函数通常与map、filter、sorted等内置函数配合使用,使代码更简洁。
五、函数的作用域
函数的作用域指的是变量可被访问的范围,分为局部作用域和全局作用域。
- 局部作用域:在函数内部定义的变量,只能在函数内部访问,称为局部变量。
def func():local_var = 10print(local_var)
func() # 输出:10
print(local_var) # 报错,local_var未定义
local_var是在func函数内部定义的局部变量,在函数外部无法访问。
- 全局作用域:在函数外部定义的变量,可在函数内部访问(但修改需要用global关键字声明),称为全局变量。
global_var = 20
def func1():print(global_var) # 访问全局变量
def func2():global global_var # 声明修改全局变量global_var = 30
func1() # 输出:20
func2()
print(global_var) # 输出:30
global_var是全局变量,func1函数内部可以直接访问;func2函数要修改全局变量,需要用global关键字声明,否则会被认为是定义了一个局部变量。
- 非局部作用域:在嵌套函数中,内部函数访问外部函数的变量(非全局变量),称为非局部变量,若要修改需用nonlocal关键字声明。
def outer_func():outer_var = 100def inner_func():nonlocal outer_var # 声明修改非局部变量outer_var = 200print("inner:", outer_var)inner_func()print("outer:", outer_var)
outer_func()
# 输出:
# inner: 200
# outer: 200
outer_var是外部函数outer_func定义的变量,内部函数inner_func要修改它,需用nonlocal关键字声明,修改后外部函数中该变量的值也会改变。
六、嵌套函数
在一个函数内部定义另一个函数,内部的函数称为嵌套函数。嵌套函数可以访问外部函数的变量(若要修改需用nonlocal关键字)。
def outer_func(x):def inner_func(y):return x + yreturn inner_func
add5 = outer_func(5)
print(add5(3)) # 输出:8
inner_func是outer_func的嵌套函数,它可以访问outer_func的参数x。outer_func(5)返回inner_func函数,然后add5(3)调用该函数,计算 5+3 的结果。
七、闭包
闭包是指嵌套函数中,内部函数引用了外部函数的变量,并且外部函数返回了内部函数。闭包可以保留外部函数的变量状态。
def make_multiplier(factor):def multiplier(number):return number * factorreturn multiplier
times3 = make_multiplier(3)
times5 = make_multiplier(5)
print(times3(10)) # 输出:30
print(times5(10)) # 输出:50
在这个例子中,multiplier是内部函数,它引用了外部函数make_multiplier的变量factor,并且make_multiplier返回了multiplier,所以形成了闭包。times3和times5分别保留了factor为 3 和 5 的状态,因此调用时会得到不同的结果。
八、递归函数
递归函数是指在函数内部调用自身的函数,常用于解决具有递归性质的问题,即问题可以分解为与原问题相似但规模更小的子问题。使用递归函数需要注意设置终止条件,避免无限递归。
递归函数的应用场景
- 数学问题:如阶乘计算、斐波那契数列、汉诺塔问题等。
- 数据结构遍历:如树的深度优先遍历、链表的某些操作等。
- 算法实现:如快速排序、归并排序等排序算法的递归实现。
实例:计算阶乘
def factorial(n):if n == 1: # 终止条件return 1return n * factorial(n - 1)
print(factorial(5)) # 输出:120,5! = 5*4*3*2*1 = 120
当n为 1 时,函数返回 1,否则返回n乘以n-1的阶乘,通过不断调用自身来计算结果。
计算斐波那契数列(第 n 项)
def fibonacci(n):if n <= 1: # 终止条件return nreturn fibonacci(n - 1) + fibonacci(n - 2)
print(fibonacci(6)) # 输出:8,斐波那契数列前几项:0,1,1,2,3,5,8...第6项是8
总结
函数通过模块化设计降低了代码冗余,其丰富的参数类型与高级特性(如闭包、递归)使其能适应从简单计算到复杂逻辑的多种场景。掌握函数的命名规范、参数传递机制、作用域规则及高级特性的应用,是编写高效、可读、可维护 Python 代码的基础。在实际开发中,需根据具体需求选择合适的函数形式与参数类型,充分发挥函数的封装与复用价值。