一、函数基础:定义与调用的核心逻辑
1. 函数的定义
在Python中,使用 def 关键字定义函数,其基本语法结构如下:
def 函数名(参数列表):
"""
函数文档字符串(可选,用于描述函数功能)
"""
函数体语句
return 返回值(可选)
①函数名:遵循Python标识符命名规则,需直观反映函数功能(例如 calculate_area 表示计算面积)。
②参数列表:可以为空,也可以包含一个或多个参数,用于接收外部传入的数据。
③函数文档字符串:使用三引号 """ """ 包裹,用于说明函数的功能、参数含义及返回值类型,是良好编程习惯的体现。
④函数体语句:实现具体功能的代码块。
⑤return语句:用于结束函数并返回结果,若省略则默认返回 None 。
例如,定义一个计算两数之和的函数:
def add_numbers(a, b):
"""
该函数接收两个参数,返回它们的和
:param a: 第一个数字
:param b: 第二个数字
:return: 两数之和
"""
return a + b
2. 函数的调用
定义函数后,通过函数名加括号的方式调用函数,并传入相应参数:
result = add_numbers(3, 5)
print(result) # 输出8
调用函数时,传入的参数数量和类型需与函数定义时匹配,否则会抛出 TypeError 异常。例如:
# 错误调用,参数数量不匹配
# add_numbers(3) # 抛出TypeError: add_numbers() missing 1 required positional argument: 'b'
二、函数参数:灵活的数据传递方式
1. 位置参数
位置参数是最基本的参数传递方式,调用函数时需按照参数定义的顺序传入对应的值。例如:
def print_info(name, age):
print(f"姓名:{name},年龄:{age}")
print_info("Alice", 25) # 姓名:Alice,年龄:25
2. 关键字参数
使用关键字参数调用函数时,可以不遵循参数定义的顺序,通过“参数名=值”的形式明确指定每个参数的值。例如:
print_info(age=30, name="Bob") # 姓名:Bob,年龄:30
3. 默认参数
定义函数时可为参数设置默认值,调用函数时若不传入该参数,则使用默认值。例如:
def greet(name, message="你好"):
print(f"{name},{message}!")
greet("Charlie") # Charlie,你好!
greet("David", "早上好") # David,早上好!
4. 可变参数
当函数需要处理不确定数量的参数时,可使用可变参数,分为以下两种类型:
①可变位置参数(*args):将多个位置参数收集为一个元组。
def sum_numbers(*args):
result = 0
for num in args:
result += num
return result
print(sum_numbers(1, 2, 3, 4)) # 输出10
②**可变关键字参数(kwargs):将多个关键字参数收集为一个字典。
def print_student_info(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
print_student_info(name="Eve", age=22, major="Computer Science")
5. 参数组合使用
在函数定义中,多种参数类型可以组合使用,但需遵循固定的顺序:位置参数、默认参数、可变位置参数(*args)、可变关键字参数(**kwargs)。例如:
def func(a, b=10, *args, **kwargs):
print(f"a: {a}, b: {b}, args: {args}, kwargs: {kwargs}")
func(1, 2, 3, 4, c=5, d=6)
# 输出:a: 1, b: 2, args: (3, 4), kwargs: {'c': 5, 'd': 6}
三、函数返回值:结果的输出与处理
函数通过 return 语句返回结果,返回值可以是任意数据类型,如数值、字符串、列表、字典甚至其他函数。例如:
# 返回列表
def get_fruits():
return ["apple", "banana", "cherry"]
# 返回字典
def get_student_info():
return {"name": "Frank", "age": 23, "major": "Math"}
# 返回函数(高阶函数)
def outer_function():
def inner_function():
print("这是内部函数")
return inner_function
result_list = get_fruits()
result_dict = get_student_info()
inner_func = outer_function()
inner_func() # 调用内部函数
如果函数中没有 return 语句,或者 return 后不跟任何值,则函数默认返回 None 。例如:
def print_message():
print("Hello, World!")
msg = print_message()
print(msg) # 输出None
四、函数使用中的常见问题与解决方案
1. 参数传递的“陷阱”
在Python中,函数参数传递遵循“赋值传递”原则:
①对于不可变数据类型(如数字、字符串、元组),函数内对参数的修改不会影响外部变量。
def change_number(num):
num = 10 # 修改局部变量num
x = 5
change_number(x)
print(x) # 输出5,x的值未改变
②对于可变数据类型(如列表、字典),函数内对参数的修改会影响外部变量。
def change_list(lst):
lst.append(4) # 修改列表
my_list = [1, 2, 3]
change_list(my_list)
print(my_list) # 输出[1, 2, 3, 4]
若不想修改原始数据,可通过切片(如 lst.copy() )或函数参数传递副本。
2. 作用域问题
Python使用LEGB规则(Local, Enclosing, Global, Built-in)查找变量:
①局部作用域(Local):函数内部定义的变量。
②嵌套作用域(Enclosing):嵌套函数中,内层函数可访问外层函数的变量。
③全局作用域(Global):模块顶层定义的变量,使用 global 关键字在函数内修改全局变量。
count = 10
def modify_count():
global count
count = 20
modify_count()
print(count) # 输出20
④内置作用域(Built-in):Python内置的函数和变量(如 print 、 len )。
3. 递归函数栈溢出
递归函数是指在函数内部调用自身的函数。虽然递归可以简洁地解决某些问题(如计算阶乘、遍历树形结构),但如果递归深度过深,会导致栈溢出错误。例如,计算阶乘的递归函数:
def factorial(n):
if n == 0:
return 1
return n * factorial(n - 1)
# 当n过大时,会抛出RecursionError: maximum recursion depth exceeded
# factorial(1000)
解决方法包括使用循环替代递归,或通过调整Python的递归深度限制(不推荐,可能导致程序崩溃)。
五、总结
函数是Python编程的核心概念之一,通过合理定义和调用函数,可以有效提升代码的复用性、可读性和可维护性。从基础的函数定义与调用,到复杂的参数传递和返回值处理,再到常见问题的解决,每个环节都需要开发者深入理解和实践。掌握函数的使用技巧,不仅能让编程更加高效,还能为构建大型项目奠定坚实基础。随着学习的深入,结合面向对象编程、模块导入等知识,函数的应用场景将更加广泛。
1899

被折叠的 条评论
为什么被折叠?



