Skip to content

Python 函数

函数是 Python 中组织代码的基本单元,用于封装可重用的代码块。本章节将详细介绍 Python 中的函数定义、调用、参数传递、返回值等内容。

函数的定义

在 Python 中,使用 def 关键字来定义函数。

基本语法

python
def function_name(parameters):
    """docstring"""
    # 函数体
    return expression
  • def:定义函数的关键字。
  • 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 中,函数参数的传递顺序必须是:

  1. 位置参数
  2. 默认参数
  3. *args
  4. **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

函数的应用场景

函数在以下场景中特别有用:

  1. 代码重用:将重复使用的代码封装成函数,避免代码冗余。
  2. 模块化:将复杂的问题分解成多个小函数,提高代码的可读性和可维护性。
  3. 抽象:隐藏实现细节,只暴露接口,便于使用。
  4. 测试:函数是测试的基本单位,便于进行单元测试。

示例:

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 中的函数相关内容,包括:

  1. 函数的定义和调用
  2. 函数的参数类型:位置参数、关键字参数、默认参数、可变参数
  3. 函数的返回值:单个返回值、多个返回值、提前返回
  4. 函数的文档字符串
  5. 函数的作用域:局部变量、全局变量、非局部变量
  6. 嵌套函数和递归函数
  7. 函数的应用场景

掌握函数的使用对于编写模块化、可重用的 Python 代码非常重要。