行莫
行莫
发布于 2025-11-16 / 6 阅读
0
0

2.Python 函数详解教程

2.Python 函数详解教程

引言

函数是 Python 编程的核心概念之一,它允许我们将代码组织成可重用的块。掌握函数的使用,能够让你的代码更加模块化、可维护和高效。本教程将系统地讲解 Python 函数的各个方面,每个概念都配有可直接运行的代码示例。

学习建议:

  • 阅读每个示例代码
  • 复制代码到 Python 解释器或 IDE 中运行
  • 尝试修改代码,观察结果变化
  • 完成每个部分的练习

第一部分:函数基础

1. 什么是函数

函数是一段可重用的代码块,用于执行特定的任务。使用函数可以:

  • 代码复用:避免重复编写相同的代码
  • 模块化:将复杂问题分解为小问题
  • 易于维护:修改功能时只需修改函数定义

2. 定义和调用函数

基本语法:

def function_name(parameters):
    """函数文档字符串(可选)"""
    # 函数体
    return value  # 返回值(可选)

示例 1:最简单的函数

# 定义一个简单的函数
def greet():
    print("Hello, Python!")

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

运行测试:

# 复制以下代码到 Python 解释器运行
def say_hello():
    print("你好,世界!")

say_hello()
say_hello()
say_hello()

示例 2:带参数的函数

# 定义带参数的函数
def greet(name):
    print(f"Hello, {name}!")

# 调用函数并传入参数
greet("Alice")    # 输出:Hello, Alice!
greet("Bob")      # 输出:Hello, Bob!
greet("Charlie")  # 输出:Hello, Charlie!

运行测试:

# 复制以下代码到 Python 解释器运行
def introduce(name, age):
    print(f"我的名字是 {name},今年 {age} 岁。")

introduce("张三", 25)
introduce("李四", 30)

3. 返回值

函数可以使用 return 语句返回一个值。如果没有 return 语句,函数默认返回 None

示例 1:返回单个值

# 定义返回值的函数
def add(a, b):
    result = a + b
    return result

# 调用函数并使用返回值
sum_result = add(3, 5)
print(sum_result)  # 输出:8

# 直接在表达式中使用
print(add(10, 20))  # 输出:30
print(add(7, 3) * 2)  # 输出:20

运行测试:

# 复制以下代码到 Python 解释器运行
def multiply(x, y):
    return x * y

result = multiply(6, 7)
print(f"6 × 7 = {result}")  # 输出:6 × 7 = 42

# 链式调用
print(multiply(2, multiply(3, 4)))  # 输出:24

示例 2:返回多个值(元组)

# Python 函数可以返回多个值(实际上是返回一个元组)
def get_name_and_age():
    name = "Alice"
    age = 25
    return name, age  # 返回元组

# 接收返回值
person_name, person_age = get_name_and_age()
print(f"姓名:{person_name},年龄:{person_age}")  # 输出:姓名:Alice,年龄:25

# 或者接收整个元组
info = get_name_and_age()
print(info)  # 输出:('Alice', 25)
print(type(info))  # 输出:<class 'tuple'>

运行测试:

# 复制以下代码到 Python 解释器运行
def calculate(x, y):
    sum_result = x + y
    product = x * y
    difference = x - y
    return sum_result, product, difference

a, b, c = calculate(10, 3)
print(f"和:{a},积:{b},差:{c}")  # 输出:和:13,积:30,差:7

示例 3:提前返回

# 函数可以使用多个 return 语句
def check_positive(number):
    if number > 0:
        return "正数"
    elif number < 0:
        return "负数"
    else:
        return "零"

print(check_positive(5))   # 输出:正数
print(check_positive(-3))  # 输出:负数
print(check_positive(0))   # 输出:零

运行测试:

# 复制以下代码到 Python 解释器运行
def is_even(num):
    if num % 2 == 0:
        return True
    return False

print(is_even(4))  # 输出:True
print(is_even(7))  # 输出:False

第二部分:函数参数

1. 位置参数

位置参数是按照定义顺序传递的参数。

def introduce(name, age, city):
    print(f"我是 {name}{age} 岁,来自 {city}。")

# 必须按照顺序传递参数
introduce("张三", 25, "北京")  # 输出:我是 张三,25 岁,来自 北京。
introduce("李四", 30, "上海")  # 输出:我是 李四,30 岁,来自 上海。

# 错误示例:参数顺序错误
# introduce(25, "张三", "北京")  # 这会导致错误或意外结果

运行测试:

# 复制以下代码到 Python 解释器运行
def calculate_area(length, width):
    area = length * width
    return area

print(f"矩形面积:{calculate_area(5, 3)}")  # 输出:矩形面积:15

2. 关键字参数

使用参数名来传递参数,可以不按顺序。

def introduce(name, age, city):
    print(f"我是 {name}{age} 岁,来自 {city}。")

# 使用关键字参数,可以不按顺序
introduce(age=25, name="张三", city="北京")  # 输出:我是 张三,25 岁,来自 北京。
introduce(city="上海", name="李四", age=30)  # 输出:我是 李四,30 岁,来自 上海。

# 混合使用位置参数和关键字参数
introduce("王五", age=28, city="广州")  # 位置参数必须在关键字参数之前

运行测试:

# 复制以下代码到 Python 解释器运行
def create_profile(name, email, age, city):
    print(f"姓名:{name}")
    print(f"邮箱:{email}")
    print(f"年龄:{age}")
    print(f"城市:{city}")

# 使用关键字参数
create_profile(email="test@example.com", name="测试用户", city="深圳", age=22)

3. 默认参数

可以为参数设置默认值,调用时可以不传递这些参数。

# 定义带默认参数的函数
def greet(name, greeting="Hello"):
    print(f"{greeting}, {name}!")

# 使用默认值
greet("Alice")  # 输出:Hello, Alice!

# 覆盖默认值
greet("Bob", "Hi")  # 输出:Hi, Bob!
greet("Charlie", greeting="Good morning")  # 输出:Good morning, Charlie!

运行测试:

# 复制以下代码到 Python 解释器运行
def power(base, exponent=2):
    """计算 base 的 exponent 次方"""
    return base ** exponent

print(power(3))      # 输出:9(使用默认值 exponent=2)
print(power(3, 3))   # 输出:27
print(power(2, 10))  # 输出:1024

重要提示:默认参数的值在函数定义时计算一次

# 注意:默认参数如果是可变对象(如列表、字典),要特别小心
def add_item(item, my_list=[]):  # 不推荐这样做
    my_list.append(item)
    return my_list

# 这会导致意外的结果
print(add_item("apple"))   # 输出:['apple']
print(add_item("banana"))  # 输出:['apple', 'banana'](意外!)

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

print(add_item_correct("apple"))   # 输出:['apple']
print(add_item_correct("banana"))  # 输出:['banana'](正确!)

运行测试:

# 复制以下代码到 Python 解释器运行
# 测试默认参数陷阱
def bad_function(x, items=[]):
    items.append(x)
    return items

def good_function(x, items=None):
    if items is None:
        items = []
    items.append(x)
    return items

print("错误示例:")
print(bad_function(1))  # 输出:[1]
print(bad_function(2))  # 输出:[1, 2](意外!)

print("\n正确示例:")
print(good_function(1))  # 输出:[1]
print(good_function(2))  # 输出:[2](正确!)

4. 可变位置参数(*args)

使用 *args 可以接收任意数量的位置参数。

# *args 接收任意数量的位置参数,打包成元组
def sum_all(*args):
    print(f"接收到的参数:{args}")
    print(f"参数类型:{type(args)}")
    total = 0
    for num in args:
        total += num
    return total

print(sum_all(1, 2, 3))           # 输出:接收到的参数:(1, 2, 3),总和:6
print(sum_all(1, 2, 3, 4, 5))     # 输出:接收到的参数:(1, 2, 3, 4, 5),总和:15
print(sum_all(10))                # 输出:接收到的参数:(10,),总和:10
print(sum_all())                  # 输出:接收到的参数:(),总和:0

运行测试:

# 复制以下代码到 Python 解释器运行
def print_info(*args):
    print(f"共接收到 {len(args)} 个参数:")
    for i, arg in enumerate(args, 1):
        print(f"  参数 {i}{arg}")

print_info("苹果", "香蕉", "橙子")
print_info(1, 2, 3, 4, 5)

*混合使用位置参数和 args:

def introduce(name, *hobbies):
    print(f"我是 {name},我的爱好有:")
    for hobby in hobbies:
        print(f"  - {hobby}")

introduce("张三", "读书", "游泳", "编程")
# 输出:
# 我是 张三,我的爱好有:
#   - 读书
#   - 游泳
#   - 编程

运行测试:

# 复制以下代码到 Python 解释器运行
def calculate_average(first, *rest):
    """计算平均值,第一个参数单独处理"""
    total = first + sum(rest)
    count = 1 + len(rest)
    return total / count

print(calculate_average(10, 20, 30))      # 输出:20.0
print(calculate_average(5, 10, 15, 20))   # 输出:12.5

5. 可变关键字参数(**kwargs)

使用 **kwargs 可以接收任意数量的关键字参数。

# **kwargs 接收任意数量的关键字参数,打包成字典
def print_info(**kwargs):
    print(f"接收到的关键字参数:{kwargs}")
    print(f"参数类型:{type(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'}
# 参数类型:<class 'dict'>
# name: Alice
# age: 25
# city: Beijing

print_info(title="Python", version=3.11)
# 输出:
# 接收到的关键字参数:{'title': 'Python', 'version': 3.11}
# title: Python
# version: 3.11

运行测试:

# 复制以下代码到 Python 解释器运行
def create_user(**kwargs):
    print("创建用户:")
    for key, value in kwargs.items():
        print(f"  {key}: {value}")

create_user(username="testuser", email="test@example.com", age=25)

混合使用所有参数类型:

# 参数顺序:位置参数 -> *args -> 关键字参数 -> **kwargs
def complex_function(required, *args, default="默认值", **kwargs):
    print(f"必需参数:{required}")
    print(f"可变位置参数:{args}")
    print(f"默认参数:{default}")
    print(f"可变关键字参数:{kwargs}")

complex_function("必需", 1, 2, 3, default="自定义", key1="value1", key2="value2")
# 输出:
# 必需参数:必需
# 可变位置参数:(1, 2, 3)
# 默认参数:自定义
# 可变关键字参数:{'key1': 'value1', 'key2': 'value2'}

运行测试:

# 复制以下代码到 Python 解释器运行
def flexible_function(name, *scores, subject="数学", **info):
    print(f"学生:{name}")
    print(f"科目:{subject}")
    print(f"成绩:{scores}")
    print(f"其他信息:{info}")

flexible_function("小明", 85, 90, 88, subject="语文", class_name="三年级", teacher="李老师")

第三部分:函数文档字符串

文档字符串(docstring)用于描述函数的功能、参数和返回值。

def calculate_area(length, width):
    """
    计算矩形的面积
    
    参数:
        length (float): 矩形的长度
        width (float): 矩形的宽度
    
    返回:
        float: 矩形的面积
    """
    return length * width

# 查看文档字符串
print(calculate_area.__doc__)
help(calculate_area)

运行测试:

# 复制以下代码到 Python 解释器运行
def factorial(n):
    """
    计算阶乘
    
    参数:
        n (int): 非负整数
    
    返回:
        int: n 的阶乘
    
    示例:
        >>> factorial(5)
        120
    """
    if n <= 1:
        return 1
    return n * factorial(n - 1)

# 查看文档
print(factorial.__doc__)
print(f"5! = {factorial(5)}")

第四部分:Lambda 函数(匿名函数)

Lambda 函数是一种简洁的函数定义方式,适用于简单的函数。

基本语法:

lambda arguments: expression

示例:

# 普通函数定义
def add(x, y):
    return x + y

# Lambda 函数等价写法
add_lambda = lambda x, y: x + y

print(add(3, 5))         # 输出:8
print(add_lambda(3, 5))  # 输出:8

运行测试:

# 复制以下代码到 Python 解释器运行
# Lambda 函数常用于需要函数作为参数的场景
numbers = [1, 2, 3, 4, 5]

# 使用 lambda 函数进行映射
squared = list(map(lambda x: x ** 2, numbers))
print(squared)  # 输出:[1, 4, 9, 16, 25]

# 使用 lambda 函数进行过滤
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens)  # 输出:[2, 4]

# 使用 lambda 函数进行排序
pairs = [(1, 3), (2, 1), (3, 2)]
sorted_pairs = sorted(pairs, key=lambda x: x[1])
print(sorted_pairs)  # 输出:[(2, 1), (3, 2), (1, 3)]

更多 Lambda 示例:

# Lambda 函数示例集合
# 1. 单参数
square = lambda x: x ** 2
print(square(5))  # 输出:25

# 2. 无参数
get_pi = lambda: 3.14159
print(get_pi())  # 输出:3.14159

# 3. 多参数
multiply = lambda x, y, z: x * y * z
print(multiply(2, 3, 4))  # 输出:24

# 4. 条件表达式
max_value = lambda a, b: a if a > b else b
print(max_value(10, 20))  # 输出:20

运行测试:

# 复制以下代码到 Python 解释器运行
# 使用 lambda 函数处理列表
data = [
    {"name": "Alice", "age": 25},
    {"name": "Bob", "age": 30},
    {"name": "Charlie", "age": 20}
]

# 按年龄排序
sorted_by_age = sorted(data, key=lambda x: x["age"])
for person in sorted_by_age:
    print(f"{person['name']}: {person['age']} 岁")

第五部分:变量作用域

1. 局部变量和全局变量

# 全局变量
global_var = "我是全局变量"

def test_scope():
    # 局部变量
    local_var = "我是局部变量"
    print(f"函数内部 - 全局变量:{global_var}")
    print(f"函数内部 - 局部变量:{local_var}")

test_scope()
print(f"函数外部 - 全局变量:{global_var}")
# print(local_var)  # 错误!局部变量在函数外部不可访问

运行测试:

# 复制以下代码到 Python 解释器运行
x = 10  # 全局变量

def modify_x():
    x = 20  # 创建局部变量,不影响全局变量
    print(f"函数内部 x = {x}")

modify_x()
print(f"函数外部 x = {x}")  # 输出:函数外部 x = 10

2. global 关键字

使用 global 关键字可以在函数内部修改全局变量。

count = 0  # 全局变量

def increment():
    global count  # 声明使用全局变量
    count += 1
    print(f"计数:{count}")

increment()  # 输出:计数:1
increment()  # 输出:计数:2
increment()  # 输出:计数:3
print(f"最终计数:{count}")  # 输出:最终计数:3

运行测试:

# 复制以下代码到 Python 解释器运行
balance = 1000  # 全局变量:账户余额

def deposit(amount):
    global balance
    balance += amount
    print(f"存入 {amount},当前余额:{balance}")

def withdraw(amount):
    global balance
    if amount <= balance:
        balance -= amount
        print(f"取出 {amount},当前余额:{balance}")
    else:
        print("余额不足!")

deposit(500)
withdraw(300)
withdraw(1500)  # 余额不足

3. nonlocal 关键字

nonlocal 用于在嵌套函数中修改外层函数的变量。

def outer():
    x = "外层变量"
    
    def inner():
        nonlocal x  # 声明使用外层函数的变量
        x = "修改后的外层变量"
        print(f"内部函数:{x}")
    
    print(f"调用 inner 前:{x}")
    inner()
    print(f"调用 inner 后:{x}")

outer()
# 输出:
# 调用 inner 前:外层变量
# 内部函数:修改后的外层变量
# 调用 inner 后:修改后的外层变量

运行测试:

# 复制以下代码到 Python 解释器运行
def counter():
    count = 0
    
    def increment():
        nonlocal count
        count += 1
        return count
    
    return increment

# 创建计数器
counter1 = counter()
print(counter1())  # 输出:1
print(counter1())  # 输出:2
print(counter1())  # 输出:3

# 创建另一个独立的计数器
counter2 = counter()
print(counter2())  # 输出:1(独立的计数器)

第六部分:闭包

闭包是指内部函数可以访问外部函数的变量,即使外部函数已经执行完毕。

def outer_function(x):
    # 外部函数的变量
    outer_var = x
    
    def inner_function(y):
        # 内部函数可以访问外部函数的变量
        return outer_var + y
    
    # 返回内部函数(注意:没有调用,只是返回函数对象)
    return inner_function

# 创建闭包
closure = outer_function(10)
print(closure(5))   # 输出:15
print(closure(20))  # 输出:30

运行测试:

# 复制以下代码到 Python 解释器运行
def multiplier(factor):
    """创建一个乘法器函数"""
    def multiply(number):
        return number * factor
    return multiply

# 创建不同的乘法器
double = multiplier(2)
triple = multiplier(3)

print(double(5))   # 输出:10
print(triple(5))   # 输出:15
print(double(10))  # 输出:20

实用的闭包示例:

def create_validator(min_value, max_value):
    """创建一个数值验证器"""
    def validate(value):
        if min_value <= value <= max_value:
            return True, f"值 {value} 在有效范围内"
        else:
            return False, f"值 {value} 超出范围 [{min_value}, {max_value}]"
    return validate

# 创建年龄验证器(0-150)
age_validator = create_validator(0, 150)
print(age_validator(25))   # 输出:(True, '值 25 在有效范围内')
print(age_validator(200))  # 输出:(False, '值 200 超出范围 [0, 150]')

# 创建分数验证器(0-100)
score_validator = create_validator(0, 100)
print(score_validator(85))  # 输出:(True, '值 85 在有效范围内')
print(score_validator(150)) # 输出:(False, '值 150 超出范围 [0, 100]')

运行测试:

# 复制以下代码到 Python 解释器运行
def power_factory(exponent):
    """创建幂函数工厂"""
    def power(base):
        return base ** exponent
    return power

# 创建不同的幂函数
square = power_factory(2)
cube = power_factory(3)

print(square(4))  # 输出:16 (4^2)
print(cube(4))    # 输出:64 (4^3)

第七部分:递归函数

递归函数是调用自身的函数。递归是解决某些问题的优雅方法。

基本结构:

def recursive_function(parameters):
    # 基本情况(终止条件)
    if base_case:
        return base_value
    
    # 递归情况
    return recursive_function(modified_parameters)

示例 1:计算阶乘

def factorial(n):
    """
    计算 n 的阶乘
    5! = 5 × 4 × 3 × 2 × 1 = 120
    """
    # 基本情况
    if n <= 1:
        return 1
    # 递归情况
    return n * factorial(n - 1)

print(factorial(5))   # 输出:120
print(factorial(3))   # 输出:6
print(factorial(0))   # 输出:1

运行测试:

# 复制以下代码到 Python 解释器运行
def factorial(n):
    if n <= 1:
        return 1
    return n * factorial(n - 1)

# 测试
for i in range(6):
    print(f"{i}! = {factorial(i)}")

示例 2:斐波那契数列

def fibonacci(n):
    """
    计算斐波那契数列的第 n 项
    0, 1, 1, 2, 3, 5, 8, 13, 21, ...
    """
    if n <= 0:
        return 0
    elif n == 1:
        return 1
    else:
        return fibonacci(n - 1) + fibonacci(n - 2)

# 生成前 10 个斐波那契数
for i in range(10):
    print(f"F({i}) = {fibonacci(i)}")

运行测试:

# 复制以下代码到 Python 解释器运行
def fibonacci(n):
    if n <= 0:
        return 0
    elif n == 1:
        return 1
    else:
        return fibonacci(n - 1) + fibonacci(n - 2)

# 打印前 10 个斐波那契数
print("斐波那契数列:")
for i in range(10):
    print(f"F({i}) = {fibonacci(i)}")

示例 3:计算列表元素之和

def sum_list(numbers):
    """递归计算列表元素之和"""
    if len(numbers) == 0:
        return 0
    else:
        return numbers[0] + sum_list(numbers[1:])

print(sum_list([1, 2, 3, 4, 5]))  # 输出:15
print(sum_list([10, 20, 30]))     # 输出:60

运行测试:

# 复制以下代码到 Python 解释器运行
def sum_list(numbers):
    if not numbers:
        return 0
    return numbers[0] + sum_list(numbers[1:])

test_lists = [
    [1, 2, 3],
    [10, 20, 30, 40],
    [5],
    []
]

for lst in test_lists:
    print(f"sum_list({lst}) = {sum_list(lst)}")

递归的注意事项:

  • 必须有终止条件(基本情况)
  • 递归调用必须向基本情况靠近
  • Python 默认递归深度限制为 1000(可通过 sys.setrecursionlimit() 修改)

第八部分:装饰器

装饰器是 Python 的高级特性,允许在不修改原函数的情况下增强函数功能。

1. 函数作为对象

在 Python 中,函数是一等对象,可以作为参数传递、赋值给变量等。

def greet(name):
    return f"Hello, {name}!"

# 函数可以作为变量
say_hello = greet
print(say_hello("Alice"))  # 输出:Hello, Alice!

# 函数可以作为参数
def call_function(func, arg):
    return func(arg)

print(call_function(greet, "Bob"))  # 输出:Hello, Bob!

运行测试:

# 复制以下代码到 Python 解释器运行
def add(x, y):
    return x + y

def multiply(x, y):
    return x * y

def calculate(func, a, b):
    return func(a, b)

print(calculate(add, 5, 3))        # 输出:8
print(calculate(multiply, 5, 3))   # 输出:15

2. 简单装饰器

def my_decorator(func):
    def wrapper():
        print("装饰器:函数执行前")
        result = func()
        print("装饰器:函数执行后")
        return result
    return wrapper

@my_decorator
def say_hello():
    print("Hello, World!")

say_hello()
# 输出:
# 装饰器:函数执行前
# Hello, World!
# 装饰器:函数执行后

运行测试:

# 复制以下代码到 Python 解释器运行
def timer_decorator(func):
    import time
    def wrapper():
        start = time.time()
        result = func()
        end = time.time()
        print(f"函数执行时间:{end - start:.4f} 秒")
        return result
    return wrapper

@timer_decorator
def slow_function():
    import time
    time.sleep(1)
    return "完成"

slow_function()

3. 带参数的装饰器

def repeat(times):
    """装饰器工厂:创建重复执行函数的装饰器"""
    def decorator(func):
        def wrapper(*args, **kwargs):
            for i in range(times):
                print(f"第 {i + 1} 次执行:")
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator

@repeat(times=3)
def greet(name):
    print(f"Hello, {name}!")

greet("Alice")
# 输出:
# 第 1 次执行:
# Hello, Alice!
# 第 2 次执行:
# Hello, Alice!
# 第 3 次执行:
# Hello, Alice!

运行测试:

# 复制以下代码到 Python 解释器运行
def log_calls(func):
    """记录函数调用的装饰器"""
    def wrapper(*args, **kwargs):
        print(f"调用函数:{func.__name__}")
        print(f"参数:args={args}, kwargs={kwargs}")
        result = func(*args, **kwargs)
        print(f"返回值:{result}")
        return result
    return wrapper

@log_calls
def add(x, y):
    return x + y

@log_calls
def multiply(x, y):
    return x * y

add(3, 5)
multiply(4, 6)

4. 使用 functools.wraps 保留函数元信息

from functools import wraps

def my_decorator(func):
    @wraps(func)  # 保留原函数的元信息
    def wrapper(*args, **kwargs):
        print(f"调用函数:{func.__name__}")
        return func(*args, **kwargs)
    return wrapper

@my_decorator
def example():
    """这是一个示例函数"""
    pass

print(example.__name__)  # 输出:example(而不是 wrapper)
print(example.__doc__)   # 输出:这是一个示例函数

运行测试:

# 复制以下代码到 Python 解释器运行
from functools import wraps

def count_calls(func):
    """统计函数调用次数的装饰器"""
    @wraps(func)
    def wrapper(*args, **kwargs):
        wrapper.call_count += 1
        print(f"{func.__name__} 被调用了 {wrapper.call_count} 次")
        return func(*args, **kwargs)
    wrapper.call_count = 0
    return wrapper

@count_calls
def greet(name):
    return f"Hello, {name}!"

greet("Alice")
greet("Bob")
greet("Charlie")
print(f"函数名:{greet.__name__}")  # 输出:greet

第九部分:内置函数和常用函数

1. 常用内置函数

# 1. len() - 获取长度
print(len("Hello"))        # 输出:5
print(len([1, 2, 3, 4]))  # 输出:4

# 2. type() - 获取类型
print(type(5))            # 输出:<class 'int'>
print(type("hello"))      # 输出:<class 'str'>

# 3. isinstance() - 类型检查
print(isinstance(5, int))      # 输出:True
print(isinstance("hello", int)) # 输出:False

# 4. range() - 生成数字序列
print(list(range(5)))        # 输出:[0, 1, 2, 3, 4]
print(list(range(1, 5)))     # 输出:[1, 2, 3, 4]
print(list(range(1, 10, 2))) # 输出:[1, 3, 5, 7, 9]

# 5. enumerate() - 枚举
for i, value in enumerate(["a", "b", "c"]):
    print(f"索引 {i}: {value}")

# 6. zip() - 组合多个序列
names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 35]
for name, age in zip(names, ages):
    print(f"{name}: {age} 岁")

运行测试:

# 复制以下代码到 Python 解释器运行
# 使用内置函数处理数据
numbers = [1, 2, 3, 4, 5]

print(f"最大值:{max(numbers)}")
print(f"最小值:{min(numbers)}")
print(f"总和:{sum(numbers)}")
print(f"平均值:{sum(numbers) / len(numbers)}")

# 使用 map 和 filter
squared = list(map(lambda x: x ** 2, numbers))
evens = list(filter(lambda x: x % 2 == 0, numbers))

print(f"平方:{squared}")
print(f"偶数:{evens}")

2. 自定义实用函数示例

def find_max_min(numbers):
    """找到列表中的最大值和最小值"""
    if not numbers:
        return None, None
    return max(numbers), min(numbers)

def count_words(text):
    """统计文本中的单词数"""
    words = text.split()
    return len(words)

def reverse_string(text):
    """反转字符串"""
    return text[::-1]

# 测试
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
max_val, min_val = find_max_min(numbers)
print(f"最大值:{max_val},最小值:{min_val}")

text = "Python 是一门优秀的编程语言"
print(f"单词数:{count_words(text)}")
print(f"反转后:{reverse_string(text)}")

运行测试:

# 复制以下代码到 Python 解释器运行
def is_palindrome(text):
    """检查字符串是否为回文"""
    cleaned = text.lower().replace(" ", "")
    return cleaned == cleaned[::-1]

def remove_duplicates(items):
    """移除列表中的重复元素,保持顺序"""
    seen = set()
    result = []
    for item in items:
        if item not in seen:
            seen.add(item)
            result.append(item)
    return result

# 测试
print(is_palindrome("racecar"))      # 输出:True
print(is_palindrome("Python"))       # 输出:False
print(remove_duplicates([1, 2, 2, 3, 3, 3, 4]))  # 输出:[1, 2, 3, 4]

第十部分:函数最佳实践

1. 函数命名规范

# 好的命名:清晰、描述性
def calculate_total_price():
    pass

def get_user_by_id():
    pass

# 不好的命名:不清晰
def calc():
    pass

def func1():
    pass

2. 单一职责原则

# 好的设计:每个函数只做一件事
def validate_email(email):
    """验证邮箱格式"""
    return "@" in email and "." in email.split("@")[1]

def send_email(email, message):
    """发送邮件"""
    if validate_email(email):
        print(f"发送邮件到 {email}: {message}")
    else:
        print("邮箱格式无效")

# 不好的设计:一个函数做多件事
def validate_and_send_email(email, message):
    """验证并发送邮件(违反单一职责原则)"""
    if "@" in email:
        print(f"发送邮件到 {email}: {message}")

3. 函数应该简短

# 好的设计:函数简短,易于理解
def calculate_discount(price, discount_rate):
    """计算折扣后的价格"""
    return price * (1 - discount_rate)

def calculate_tax(price, tax_rate):
    """计算税费"""
    return price * tax_rate

def calculate_final_price(price, discount_rate, tax_rate):
    """计算最终价格"""
    discounted = calculate_discount(price, discount_rate)
    return discounted + calculate_tax(discounted, tax_rate)

4. 使用类型提示(Python 3.5+)

def add(x: int, y: int) -> int:
    """添加两个整数"""
    return x + y

def greet(name: str) -> str:
    """问候某人"""
    return f"Hello, {name}!"

def process_data(data: list[str]) -> dict[str, int]:
    """处理数据列表,返回统计字典"""
    return {item: len(item) for item in data}

运行测试:

# 复制以下代码到 Python 解释器运行(Python 3.5+)
from typing import List, Dict, Optional

def find_max(numbers: List[int]) -> Optional[int]:
    """找到列表中的最大值"""
    if not numbers:
        return None
    return max(numbers)

def create_user(name: str, age: int, email: Optional[str] = None) -> Dict[str, any]:
    """创建用户字典"""
    user = {"name": name, "age": age}
    if email:
        user["email"] = email
    return user

print(find_max([1, 5, 3, 9, 2]))
print(create_user("Alice", 25, "alice@example.com"))

第十一部分:综合练习

练习 1:计算器函数

def calculator(operation, a, b):
    """
    简单的计算器函数
    
    参数:
        operation (str): 操作类型('+', '-', '*', '/')
        a (float): 第一个数字
        b (float): 第二个数字
    
    返回:
        float: 计算结果
    """
    operations = {
        '+': lambda x, y: x + y,
        '-': lambda x, y: x - y,
        '*': lambda x, y: x * y,
        '/': lambda x, y: x / y if y != 0 else None
    }
    
    func = operations.get(operation)
    if func is None:
        return None
    
    return func(a, b)

# 测试
print(calculator('+', 10, 5))  # 输出:15
print(calculator('-', 10, 5))  # 输出:5
print(calculator('*', 10, 5))  # 输出:50
print(calculator('/', 10, 5))   # 输出:2.0
print(calculator('/', 10, 0))   # 输出:None

运行测试:

# 复制以下代码到 Python 解释器运行
def calculator(operation, a, b):
    operations = {
        '+': lambda x, y: x + y,
        '-': lambda x, y: x - y,
        '*': lambda x, y: x * y,
        '/': lambda x, y: x / y if y != 0 else None
    }
    func = operations.get(operation)
    return func(a, b) if func else None

# 交互式测试
print("10 + 5 =", calculator('+', 10, 5))
print("10 - 5 =", calculator('-', 10, 5))
print("10 * 5 =", calculator('*', 10, 5))
print("10 / 5 =", calculator('/', 10, 5))

练习 2:文本处理函数集合

def word_count(text):
    """统计单词数"""
    return len(text.split())

def char_count(text, include_spaces=True):
    """统计字符数"""
    if include_spaces:
        return len(text)
    return len(text.replace(" ", ""))

def reverse_words(text):
    """反转单词顺序"""
    words = text.split()
    return " ".join(reversed(words))

def capitalize_words(text):
    """将每个单词首字母大写"""
    return " ".join(word.capitalize() for word in text.split())

# 测试
text = "python is a great programming language"
print(f"原文:{text}")
print(f"单词数:{word_count(text)}")
print(f"字符数(含空格):{char_count(text)}")
print(f"字符数(不含空格):{char_count(text, False)}")
print(f"反转单词:{reverse_words(text)}")
print(f"首字母大写:{capitalize_words(text)}")

运行测试:

# 复制以下代码到 Python 解释器运行
def analyze_text(text):
    """综合分析文本"""
    return {
        "长度": len(text),
        "单词数": len(text.split()),
        "字符数(不含空格)": len(text.replace(" ", "")),
        "大写字母数": sum(1 for c in text if c.isupper()),
        "小写字母数": sum(1 for c in text if c.islower()),
        "数字数": sum(1 for c in text if c.isdigit())
    }

result = analyze_text("Python 3.11 is Awesome!")
for key, value in result.items():
    print(f"{key}{value}")

练习 3:数据验证函数

def validate_email(email):
    """验证邮箱格式"""
    if "@" not in email:
        return False, "邮箱必须包含 @"
    
    parts = email.split("@")
    if len(parts) != 2:
        return False, "邮箱格式不正确"
    
    local, domain = parts
    if not local or not domain:
        return False, "邮箱的本地部分和域名部分不能为空"
    
    if "." not in domain:
        return False, "域名必须包含点号"
    
    return True, "邮箱格式正确"

def validate_password(password):
    """验证密码强度"""
    if len(password) < 8:
        return False, "密码长度至少 8 位"
    
    has_upper = any(c.isupper() for c in password)
    has_lower = any(c.islower() for c in password)
    has_digit = any(c.isdigit() for c in password)
    
    if not (has_upper and has_lower and has_digit):
        return False, "密码必须包含大写字母、小写字母和数字"
    
    return True, "密码强度符合要求"

# 测试
emails = ["test@example.com", "invalid.email", "user@domain"]
for email in emails:
    valid, message = validate_email(email)
    print(f"{email}: {message}")

passwords = ["Weak", "Strong123", "VERYSTRONG123"]
for pwd in passwords:
    valid, message = validate_password(pwd)
    print(f"'{pwd}': {message}")

运行测试:

# 复制以下代码到 Python 解释器运行
def validate_phone(phone):
    """验证手机号(简单版本)"""
    # 移除空格和连字符
    cleaned = phone.replace(" ", "").replace("-", "")
    
    if not cleaned.isdigit():
        return False, "手机号只能包含数字"
    
    if len(cleaned) != 11:
        return False, "手机号必须是 11 位数字"
    
    if not cleaned.startswith("1"):
        return False, "手机号必须以 1 开头"
    
    return True, "手机号格式正确"

# 测试
test_phones = ["13812345678", "12345678901", "138-1234-5678", "abc12345678"]
for phone in test_phones:
    valid, message = validate_phone(phone)
    print(f"{phone}: {message}")

总结

通过本教程,我们系统地学习了 Python 函数的各个方面:

  1. 函数基础:定义、调用、返回值
  2. 参数类型:位置参数、关键字参数、默认参数、可变参数
  3. 文档字符串:如何编写清晰的函数文档
  4. Lambda 函数:匿名函数的用法
  5. 作用域:局部变量、全局变量、nonlocal
  6. 闭包:内部函数访问外部变量
  7. 递归:函数调用自身解决问题
  8. 装饰器:增强函数功能的高级特性
  9. 最佳实践:编写高质量函数的建议

关键要点:

  • 函数是代码复用的基本单元
  • 合理使用参数可以让函数更灵活
  • 文档字符串帮助他人理解函数
  • 递归适合解决分治问题
  • 装饰器是 Python 的强大特性

下一步学习:

  • 生成器函数:使用 yield 创建生成器
  • 类方法:在类中定义方法
  • 异步函数:使用 async/await 进行异步编程
  • 函数式编程:map、filter、reduce 等
  • 设计模式:策略模式、工厂模式等

记住:多练习、多实践,才能真正掌握 Python 函数!


参考资料


祝你学习愉快!


评论