目录

Python 函数基础

学习目标

  • 理解函数的定义与调用
  • 掌握各种参数类型:位置参数、关键字参数、默认参数、可变参数
  • 理解返回值与作用域基础
  • 能够编写和调用自定义函数

一、什么是函数

函数是一段可重复使用的代码块,用于完成特定任务。使用函数可以避免重复代码,提高程序的可读性和可维护性。

# 定义函数
def greet():
    print("Hello, Python!")

# 调用函数
greet()   # Hello, Python!
greet()   # 可以多次调用

二、函数的定义与调用

基本语法

def 函数名(参数1, 参数2, ...):
    """文档字符串(可选,用于说明函数功能)"""
    # 函数体
    return 返回值   # 可选
def add(a, b):
    """返回两个数的和"""
    result = a + b
    return result

# 调用
sum_val = add(3, 5)
print(sum_val)   # 8

# 没有 return 的函数返回 None
def say_hello():
    print("Hello!")

result = say_hello()   # Hello!
print(result)          # None

三、参数类型

3.1 位置参数

def greet(name, greeting):
    print(f"{greeting}, {name}!")

greet("Alice", "Good morning")   # Good morning, Alice!
# greet("Alice")                 # TypeError: 缺少参数

3.2 关键字参数

# 调用时指定参数名,顺序可以打乱
greet(greeting="Hi", name="Bob")   # Hi, Bob!
greet(name="Charlie", greeting="Hello")   # Hello, Charlie!

# 混合使用:位置参数在前,关键字参数在后
greet("David", greeting="Hey")   # Hey, David!

3.3 默认参数

def greet(name, greeting="Hello"):
    print(f"{greeting}, {name}!")

greet("Alice")                  # Hello, Alice!(使用默认值)
greet("Bob", "Good morning")    # Good morning, Bob!(覆盖默认值)

注意:默认参数应该在非默认参数之后。

# 错误示范
# def wrong(a=1, b):   # SyntaxError
#     pass

# 正确示范
def correct(a, b=1, c=2):
    print(a, b, c)

correct(10)          # 10 1 2
correct(10, 20)      # 10 20 2
correct(10, 20, 30)  # 10 20 30

默认参数的陷阱

# 默认参数在函数定义时求值,如果默认参数是可变对象,会有意外行为
def add_item(item, items=[]):
    items.append(item)
    return items

print(add_item(1))   # [1]
print(add_item(2))   # [1, 2]   # 意外!保留了上一次的结果
print(add_item(3))   # [1, 2, 3]

# 正确做法:使用 None 作为默认值
def add_item_safe(item, items=None):
    if items is None:
        items = []
    items.append(item)
    return items

print(add_item_safe(1))   # [1]
print(add_item_safe(2))   # [2]

3.4 可变参数 *args

# *args 接收任意数量的位置参数,以元组形式传入
def sum_all(*numbers):
    total = 0
    for n in numbers:
        total += n
    return total

print(sum_all())           # 0
print(sum_all(1, 2))       # 3
print(sum_all(1, 2, 3, 4)) # 10

# args 是元组,可以迭代
print(sum_all(*[1, 2, 3])) # 6(使用 * 解包列表)

3.5 关键字可变参数 **kwargs

# **kwargs 接收任意数量的关键字参数,以字典形式传入
def print_info(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")

print_info(name="Alice", age=25, city="Beijing")
# name: Alice
# age: 25
# city: Beijing

# 使用字典解包
info = {"name": "Bob", "age": 30}
print_info(**info)

3.6 参数顺序总结

def func(pos1, pos2, default="value", *args, **kwargs):
    print(f"位置参数: {pos1}, {pos2}")
    print(f"默认参数: {default}")
    print(f"可变位置参数: {args}")
    print(f"可变关键字参数: {kwargs}")

func(1, 2)
# 位置参数: 1, 2
# 默认参数: value
# 可变位置参数: ()
# 可变关键字参数: {}

func(1, 2, "custom", 4, 5, name="Alice", age=25)
# 位置参数: 1, 2
# 默认参数: custom
# 可变位置参数: (4, 5)
# 可变关键字参数: {'name': 'Alice', 'age': 25}

四、返回值

4.1 返回单个值

def square(x):
    return x ** 2

print(square(5))   # 25

4.2 返回多个值

def get_min_max(numbers):
    return min(numbers), max(numbers)

minimum, maximum = get_min_max([3, 1, 4, 1, 5, 9])
print(minimum, maximum)   # 1 9

# 实际上是返回元组
result = get_min_max([3, 1, 4])
print(result)             # (1, 4)
print(type(result))       # <class 'tuple'>

4.3 提前返回

def divide(a, b):
    if b == 0:
        return None   # 提前返回
    return a / b

print(divide(10, 2))   # 5.0
print(divide(10, 0))   # None

五、文档字符串

def calculate_bmi(weight, height):
    """
    计算 BMI 指数

    参数:
        weight (float): 体重,单位千克
        height (float): 身高,单位米

    返回:
        float: BMI 值

    示例:
        >>> calculate_bmi(70, 1.75)
        22.857142857142858
    """
    return weight / (height ** 2)

# 查看文档
print(calculate_bmi.__doc__)

# help() 查看帮助
help(calculate_bmi)

六、综合示例

"""
简易计算器函数库
"""

def add(a, b):
    """加法"""
    return a + b

def subtract(a, b):
    """减法"""
    return a - b

def multiply(a, b):
    """乘法"""
    return a * b

def divide(a, b):
    """除法,除数为 0 时返回 None"""
    if b == 0:
        print("错误:除数不能为 0")
        return None
    return a / b

def calculator(expression):
    """
    解析并计算简单的四则运算表达式
    示例: "10 + 5", "20 * 3"
    """
    parts = expression.split()
    if len(parts) != 3:
        return None

    a = float(parts[0])
    op = parts[1]
    b = float(parts[2])

    operations = {
        "+": add,
        "-": subtract,
        "*": multiply,
        "/": divide,
    }

    if op in operations:
        return operations[op](a, b)
    return None


# 测试
print(calculator("10 + 5"))    # 15.0
print(calculator("20 * 3"))    # 60.0
print(calculator("15 / 3"))    # 5.0
print(calculator("10 / 0"))    # 错误:除数不能为 0

小结

  • 使用 def 定义函数,return 返回值
  • 参数类型:位置参数、关键字参数、默认参数、*args**kwargs
  • 默认参数使用不可变对象,如需可变对象用 None 做默认值
  • 函数可以返回多个值(实际是元组)
  • 使用文档字符串说明函数功能,可通过 __doc__help() 查看

练习

  1. 编写一个函数 is_prime(n),判断一个数是否为质数。
  2. 编写一个函数 factorial(n),计算阶乘(使用递归或循环)。
  3. 编写一个函数,接收任意数量的数字参数,返回它们的平均值、最大值和最小值。
  4. 编写一个函数 safe_divide(a, b, default=0),当除数为 0 时返回 default 值。
  5. 为以下函数编写文档字符串:
    def celsius_to_fahrenheit(c):
        return c * 9 / 5 + 32