Appearance
Python 函数
函数是 Python 中组织代码的基本单元,用于封装可重用的代码块。本章节将详细介绍 Python 中的函数定义、调用、参数传递、返回值等内容。
函数的定义
在 Python 中,使用 def 关键字来定义函数。
基本语法
python
def function_name(parameters):
"""docstring"""
# 函数体
return expressiondef:定义函数的关键字。function_name:函数的名称,应遵循 Python 的命名规范。parameters:函数的参数列表,可选。docstring:函数的文档字符串,用于描述函数的功能,可选。function_body:函数的代码块,包含具体的实现逻辑。return:返回语句,用于返回函数的结果,可选。
示例
python
# 函数的定义示例
# 无参数、无返回值的函数
def greet():
"""打印问候语"""
print("Hello, World!")
# 调用函数
greet() # 输出:Hello, World!
# 有参数、无返回值的函数
def greet_name(name):
"""打印带名称的问候语"""
print(f"Hello, {name}!")
# 调用函数
greet_name("Alice") # 输出:Hello, Alice!
# 有参数、有返回值的函数
def add(a, b):
"""计算两个数的和"""
return a + b
# 调用函数并获取返回值
result = add(3, 5)
print(f"3 + 5 = {result}") # 输出:3 + 5 = 8
# 多个返回值的函数
def get_name_and_age():
"""返回姓名和年龄"""
return "Alice", 30
# 调用函数并获取多个返回值
name, age = get_name_and_age()
print(f"姓名:{name},年龄:{age}") # 输出:姓名:Alice,年龄:30函数的参数
Python 中的函数参数有多种类型,包括位置参数、关键字参数、默认参数、可变参数等。
位置参数
位置参数是最基本的参数类型,调用函数时需要按照定义的顺序传递参数。
示例:
python
# 位置参数示例
def subtract(a, b):
"""计算两个数的差"""
return a - b
# 调用函数
result = subtract(10, 3)
print(f"10 - 3 = {result}") # 输出:10 - 3 = 7
# 错误的调用方式(参数顺序错误)
result = subtract(3, 10)
print(f"3 - 10 = {result}") # 输出:3 - 10 = -7关键字参数
关键字参数允许在调用函数时通过参数名来指定参数值,不需要按照定义的顺序传递。
示例:
python
# 关键字参数示例
def greet(name, age):
"""打印问候语和年龄"""
print(f"Hello, {name}! You are {age} years old.")
# 使用关键字参数调用函数
greet(name="Alice", age=30) # 输出:Hello, Alice! You are 30 years old.
# 改变参数顺序
greet(age=25, name="Bob") # 输出:Hello, Bob! You are 25 years old.
# 混合使用位置参数和关键字参数
greet("Charlie", age=35) # 输出:Hello, Charlie! You are 35 years old.
# 注意:位置参数必须在关键字参数之前
# greet(name="David", 40) # 语法错误默认参数
默认参数允许在定义函数时为参数设置默认值,调用函数时如果不提供该参数,则使用默认值。
示例:
python
# 默认参数示例
def greet(name, greeting="Hello"):
"""打印问候语"""
print(f"{greeting}, {name}!")
# 不提供默认参数
greet("Alice") # 输出:Hello, Alice!
# 提供默认参数
greet("Bob", "Hi") # 输出:Hi, Bob!
# 使用关键字参数指定默认参数
greet("Charlie", greeting="Hey") # 输出:Hey, Charlie!
# 多个默认参数
def calculate(a, b=2, c=3):
"""计算 a + b * c"""
return a + b * c
print(calculate(1)) # 输出:7(1 + 2 * 3)
print(calculate(1, 4)) # 输出:13(1 + 4 * 3)
print(calculate(1, 4, 5)) # 输出:21(1 + 4 * 5)
print(calculate(1, c=10)) # 输出:21(1 + 2 * 10)可变参数
可变参数允许函数接受任意数量的参数,包括 *args 和 **kwargs。
*args
*args 用于接收任意数量的位置参数,这些参数会被打包成一个元组。
示例:
python
# *args 示例
def sum_numbers(*args):
"""计算任意数量数字的和"""
total = 0
for num in args:
total += num
return total
print(sum_numbers(1, 2, 3)) # 输出:6
print(sum_numbers(1, 2, 3, 4, 5)) # 输出:15
print(sum_numbers()) # 输出:0
# 混合使用普通参数和 *args
def greet(name, *args):
"""打印问候语和额外信息"""
print(f"Hello, {name}!")
if args:
print("额外信息:")
for info in args:
print(f"- {info}")
greet("Alice", "喜欢编程", "来自纽约")
# 输出:
# Hello, Alice!
# 额外信息:
# - 喜欢编程
# - 来自纽约**kwargs
**kwargs 用于接收任意数量的关键字参数,这些参数会被打包成一个字典。
示例:
python
# **kwargs 示例
def print_info(**kwargs):
"""打印任意数量的关键字参数"""
for key, value in kwargs.items():
print(f"{key}: {value}")
print_info(name="Alice", age=30, city="New York")
# 输出:
# name: Alice
# age: 30
# city: New York
# 混合使用普通参数、*args 和 **kwargs
def mixed_params(a, b, *args, **kwargs):
"""混合使用多种参数类型"""
print(f"a: {a}")
print(f"b: {b}")
if args:
print(f"args: {args}")
if kwargs:
print(f"kwargs: {kwargs}")
mixed_params(1, 2, 3, 4, 5, name="Alice", age=30)
# 输出:
# a: 1
# b: 2
# args: (3, 4, 5)
# kwargs: {'name': 'Alice', 'age': 30}参数传递的顺序
在 Python 中,函数参数的传递顺序必须是:
- 位置参数
- 默认参数
*args**kwargs
示例:
python
# 参数传递的顺序
def func(a, b=2, *args, **kwargs):
print(f"a: {a}")
print(f"b: {b}")
print(f"args: {args}")
print(f"kwargs: {kwargs}")
func(1, 3, 4, 5, 6, name="Alice", age=30)
# 输出:
# a: 1
# b: 3
# args: (4, 5, 6)
# kwargs: {'name': 'Alice', 'age': 30}函数的返回值
函数可以使用 return 语句返回一个或多个值,也可以不返回任何值(默认返回 None)。
单个返回值
示例:
python
# 单个返回值示例
def square(x):
"""计算平方"""
return x ** 2
result = square(5)
print(result) # 输出:25
# 不返回值的函数
def greet():
"""打印问候语"""
print("Hello!")
result = greet()
print(result) # 输出:None多个返回值
函数可以返回多个值,这些值会被打包成一个元组。
示例:
python
# 多个返回值示例
def get_name_and_age():
"""返回姓名和年龄"""
return "Alice", 30
# 接收多个返回值
name, age = get_name_and_age()
print(f"姓名:{name},年龄:{age}") # 输出:姓名:Alice,年龄:30
# 作为元组接收
person = get_name_and_age()
print(person) # 输出:('Alice', 30)
print(type(person)) # 输出:<class 'tuple'>
# 多个返回值的函数
def calculate(a, b):
"""返回和、差、积、商"""
return a + b, a - b, a * b, a / b
add, sub, mul, div = calculate(10, 3)
print(f"和:{add}") # 输出:和:13
print(f"差:{sub}") # 输出:差:7
print(f"积:{mul}") # 输出:积:30
print(f"商:{div}") # 输出:商:3.3333333333333335提前返回
函数可以在任何地方使用 return 语句提前返回,结束函数的执行。
示例:
python
# 提前返回示例
def is_even(num):
"""检查数字是否为偶数"""
if num % 2 == 0:
return True
return False
print(is_even(4)) # 输出:True
print(is_even(5)) # 输出:False
# 更复杂的例子
def get_grade(score):
"""根据分数返回等级"""
if score >= 90:
return "A"
elif score >= 80:
return "B"
elif score >= 70:
return "C"
elif score >= 60:
return "D"
else:
return "F"
print(get_grade(95)) # 输出:A
print(get_grade(85)) # 输出:B
print(get_grade(75)) # 输出:C
print(get_grade(65)) # 输出:D
print(get_grade(55)) # 输出:F函数的文档字符串
文档字符串(docstring)是函数定义中的第一个字符串,用于描述函数的功能、参数、返回值等信息。
基本语法
python
def function_name(parameters):
"""文档字符串
详细描述函数的功能、参数、返回值等信息
Parameters:
parameter1 (type): 参数1的描述
parameter2 (type): 参数2的描述
Returns:
return_type: 返回值的描述
"""
# 函数体
return expression示例
python
# 函数的文档字符串示例
def calculate_area(length, width):
"""计算矩形的面积
Args:
length (float): 矩形的长度
width (float): 矩形的宽度
Returns:
float: 矩形的面积
"""
return length * width
# 访问文档字符串
print(calculate_area.__doc__)
# 使用 help() 函数查看文档
help(calculate_area)
# 多行文档字符串
def complex_function(a, b, c):
"""这是一个复杂的函数
这个函数用于演示多行文档字符串的格式
可以包含多个段落,详细描述函数的功能
Parameters:
a (int): 第一个参数
b (int): 第二个参数
c (int): 第三个参数
Returns:
int: 三个参数的和
Examples:
>>> complex_function(1, 2, 3)
6
>>> complex_function(4, 5, 6)
15
"""
return a + b + c
# 查看文档
help(complex_function)函数的作用域
函数的作用域是指变量的可见范围,Python 中有两种主要的作用域:全局作用域和局部作用域。
局部变量
在函数内部定义的变量称为局部变量,只能在函数内部访问。
示例:
python
# 局部变量示例
def test():
x = 10 # 局部变量
print(f"函数内部:x = {x}")
test() # 输出:函数内部:x = 10
# 尝试在函数外部访问局部变量
# print(x) # 名称错误:name 'x' is not defined全局变量
在函数外部定义的变量称为全局变量,可以在函数内部访问,但如果要在函数内部修改全局变量,需要使用 global 关键字声明。
示例:
python
# 全局变量示例
x = 10 # 全局变量
def test():
print(f"函数内部访问全局变量:x = {x}")
test() # 输出:函数内部访问全局变量:x = 10
# 尝试在函数内部修改全局变量
def modify_global():
global x # 声明 x 是全局变量
x = 20
print(f"函数内部修改全局变量:x = {x}")
modify_global() # 输出:函数内部修改全局变量:x = 20
print(f"函数外部访问全局变量:x = {x}") # 输出:函数外部访问全局变量:x = 20
# 不使用 global 关键字的情况
def modify_local():
x = 30 # 这是一个局部变量,不是全局变量
print(f"函数内部:x = {x}")
modify_local() # 输出:函数内部:x = 30
print(f"函数外部访问全局变量:x = {x}") # 输出:函数外部访问全局变量:x = 20非局部变量
在嵌套函数中,使用 nonlocal 关键字可以访问和修改外层函数中的变量。
示例:
python
# 非局部变量示例
def outer():
x = 10 # 外层函数的变量
def inner():
nonlocal x # 声明 x 是非局部变量
x = 20
print(f"内层函数:x = {x}")
inner()
print(f"外层函数:x = {x}")
outer()
# 输出:
# 内层函数:x = 20
# 外层函数:x = 20
# 不使用 nonlocal 关键字的情况
def outer2():
x = 10 # 外层函数的变量
def inner2():
x = 30 # 这是内层函数的局部变量
print(f"内层函数:x = {x}")
inner2()
print(f"外层函数:x = {x}")
outer2()
# 输出:
# 内层函数:x = 30
# 外层函数:x = 10嵌套函数
Python 允许在函数内部定义另一个函数,这称为嵌套函数。
示例:
python
# 嵌套函数示例
def outer_function():
"""外层函数"""
print("调用外层函数")
def inner_function():
"""内层函数"""
print("调用内层函数")
# 调用内层函数
inner_function()
# 调用外层函数
outer_function()
# 输出:
# 调用外层函数
# 调用内层函数
# 尝试直接调用内层函数
# inner_function() # 名称错误:name 'inner_function' is not defined
# 嵌套函数的返回值
def outer_with_return():
"""返回内层函数"""
def inner():
return "Hello from inner"
return inner
# 获取内层函数
inner_func = outer_with_return()
# 调用内层函数
print(inner_func()) # 输出:Hello from inner递归函数
递归函数是指在函数内部调用自身的函数。
示例:
python
# 递归函数示例
def factorial(n):
"""计算阶乘"""
if n == 0 or n == 1:
return 1
else:
return n * factorial(n - 1)
print(factorial(5)) # 输出:120(5! = 5 * 4 * 3 * 2 * 1)
# 斐波那契数列
def fibonacci(n):
"""计算斐波那契数列的第 n 项"""
if n <= 0:
return 0
elif n == 1:
return 1
else:
return fibonacci(n - 1) + fibonacci(n - 2)
print(fibonacci(10)) # 输出:55(斐波那契数列的第 10 项)
# 递归的注意事项:必须有终止条件,否则会导致无限递归
# def infinite_recursion():
# infinite_recursion()
#
# infinite_recursion() # 递归错误:maximum recursion depth exceeded函数的应用场景
函数在以下场景中特别有用:
- 代码重用:将重复使用的代码封装成函数,避免代码冗余。
- 模块化:将复杂的问题分解成多个小函数,提高代码的可读性和可维护性。
- 抽象:隐藏实现细节,只暴露接口,便于使用。
- 测试:函数是测试的基本单位,便于进行单元测试。
示例:
python
# 函数的应用场景
# 1. 代码重用
print("1. 代码重用")
def calculate_area(length, width):
"""计算矩形的面积"""
return length * width
# 多次调用函数
print(f"矩形 1 的面积:{calculate_area(5, 3)}") # 输出:15
print(f"矩形 2 的面积:{calculate_area(10, 6)}") # 输出:60
print(f"矩形 3 的面积:{calculate_area(8, 4)}") # 输出:32
# 2. 模块化
print("\n2. 模块化")
def get_user_input():
"""获取用户输入"""
name = input("请输入您的姓名:")
age = int(input("请输入您的年龄:"))
return name, age
def validate_input(name, age):
"""验证用户输入"""
if not name:
return False, "姓名不能为空"
if age < 0:
return False, "年龄不能为负数"
return True, "输入有效"
def process_user_info(name, age):
"""处理用户信息"""
print(f"您好,{name}!您今年 {age} 岁。")
if age >= 18:
print("您已经成年了。")
else:
print("您还未成年。")
def main():
"""主函数"""
name, age = get_user_input()
valid, message = validate_input(name, age)
if valid:
process_user_info(name, age)
else:
print(f"错误:{message}")
# 调用主函数
# main()
# 3. 抽象
print("\n3. 抽象")
def calculate_discount(price, discount_rate):
"""计算折扣后的价格"""
discounted_price = price * (1 - discount_rate)
return round(discounted_price, 2)
# 使用函数,不需要知道具体实现
print(f"原价 100 元,折扣 20%,折后价:{calculate_discount(100, 0.2)} 元") # 输出:80.0 元
print(f"原价 200 元,折扣 10%,折后价:{calculate_discount(200, 0.1)} 元") # 输出:180.0 元总结
本章节介绍了 Python 中的函数相关内容,包括:
- 函数的定义和调用
- 函数的参数类型:位置参数、关键字参数、默认参数、可变参数
- 函数的返回值:单个返回值、多个返回值、提前返回
- 函数的文档字符串
- 函数的作用域:局部变量、全局变量、非局部变量
- 嵌套函数和递归函数
- 函数的应用场景
掌握函数的使用对于编写模块化、可重用的 Python 代码非常重要。