1. 函数基础

1.1 什么是函数

函数是组织好的、可重复使用的代码块,用于实现单一或相关联的功能。在 Python 中,函数可以提高应用的模块性和代码的重复利用率。

函数的主要作用:

  • 代码复用:避免重复编写相同功能的代码
  • 模块化:将复杂问题分解为多个小问题,每个函数解决一个小问题
  • 提高可读性:通过有意义的函数名,让代码逻辑更清晰
  • 便于调试:每个函数可以独立测试和调试

1.2 函数的定义与调用

在 Python 中,使用 def 关键字来定义函数,基本语法如下:

def 函数名(参数列表):
    """函数文档字符串(可选)"""
    函数体
    return 返回值(可选)

定义示例:

def greet(name):
    """向指定的人问好"""
    return f"Hello, {name}!"

调用示例:

# 调用函数
message = greet("Alice")
print(message)  # 输出:Hello, Alice!

# 直接打印返回值
print(greet("Bob"))  # 输出:Hello, Bob!

1.3 函数的返回值

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

返回值特性:

  • 可以返回任意类型的数据
  • 可以返回多个值(实际上是返回一个元组)
  • return 语句会立即结束函数执行

示例:

def calculate(x, y):
    """计算两个数的和、差、积"""
    add = x + y
    subtract = x - y
    multiply = x * y
    return add, subtract, multiply  # 返回元组

# 接收多个返回值
result = calculate(10, 3)
print(result)  # 输出:(13, 7, 30)

# 解包接收
sum_result, diff_result, prod_result = calculate(10, 3)
print(f"和:{sum_result}, 差:{diff_result}, 积:{prod_result}")

2. 函数参数详解

2.1 位置参数

位置参数是最基本的参数传递方式,调用时按照定义时的顺序传递参数。

def introduce(name, age, city):
    """介绍个人信息"""
    return f"{name}今年{age}岁,来自{city}。"

# 必须按顺序传递三个参数
print(introduce("张三", 25, "北京"))  # 正确
# print(introduce(25, "张三", "北京"))  # 错误:参数顺序不对

2.2 默认参数

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

def greet_person(name, greeting="你好", punctuation="!"):
    """带默认参数的问候函数"""
    return f"{greeting}{name}{punctuation}"

print(greet_person("李四"))  # 输出:你好,李四!
print(greet_person("王五", "Hello"))  # 输出:Hello,王五!
print(greet_person("赵六", "Hi", "!"))  # 输出:Hi,赵六!

# 注意:默认参数必须放在非默认参数后面
def connect(host, port=8080, timeout=30):  # 正确
    pass

# def connect(host="localhost", port, timeout=30):  # 错误

2.3 关键字参数

调用函数时,可以通过参数名指定参数值,这样可以不按顺序传递参数。

def create_user(name, age, email, country="中国"):
    """创建用户信息"""
    return {
        "name": name,
        "age": age,
        "email": email,
        "country": country
    }

# 使用关键字参数调用
user1 = create_user(name="Alice", age=25, email="alice@example.com")
user2 = create_user(email="bob@example.com", name="Bob", age=30, country="美国")

print(user1)
print(user2)

2.4 可变参数 *args 和 **kwargs

*args:接收任意数量的位置参数
def sum_all(*args):
    """计算任意数量数字的和"""
    print(f"接收到的参数:{args},类型:{type(args)}")
    return sum(args)

print(sum_all(1, 2, 3))  # 输出:6
print(sum_all(1, 2, 3, 4, 5))  # 输出:15
print(sum_all())  # 输出:0

# 与其他参数结合使用
def print_info(title, *details):
    """打印带标题的详细信息"""
    print(f"=== {title} ===")
    for i, detail in enumerate(details, 1):
        print(f"{i}. {detail}")

print_info("今日任务", "写代码", "开会", "学习Python")
**kwargs:接收任意数量的关键字参数
def print_user_info(**kwargs):
    """打印用户的所有信息"""
    print("用户信息:")
    for key, value in kwargs.items():
        print(f"  {key}: {value}")

print_user_info(name="张三", age=25, city="北京", job="工程师")

# 与其他参数结合
def create_profile(username, **extra_info):
    """创建用户档案"""
    profile = {"username": username}
    profile.update(extra_info)
    return profile

user_profile = create_profile("alice2024", 
                             email="alice@example.com", 
                             age=28, 
                             hobby=["编程", "阅读"])
print(user_profile)
同时使用 *args 和 **kwargs
def flexible_function(*args, **kwargs):
    """最灵活的函数定义方式"""
    print(f"位置参数:{args}")
    print(f"关键字参数:{kwargs}")

flexible_function(1, 2, 3, name="Alice", age=25)

2.5 参数解包

可以将列表/元组解包为位置参数,将字典解包为关键字参数。

def calculate(a, b, c):
    """计算三个数的和与平均值"""
    total = a + b + c
    average = total / 3
    return total, average

# 列表/元组解包
numbers = [10, 20, 30]
result1 = calculate(*numbers)  # 相当于 calculate(10, 20, 30)
print(f"解包列表结果:{result1}")

# 字典解包
params = {"a": 5, "b": 15, "c": 25}
result2 = calculate(**params)  # 相当于 calculate(a=5, b=15, c=25)
print(f"解包字典结果:{result2}")

# 混合使用
def complex_func(a, b, c, d=0, e=0):
    return a + b + c + d + e

args_list = [1, 2, 3]
kwargs_dict = {"d": 4, "e": 5}
result3 = complex_func(*args_list, **kwargs_dict)
print(f"混合解包结果:{result3}")  # 输出:15

3. 变量作用域

3.1 局部变量与全局变量

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

def test_scope():
    # 局部变量
    local_var = "我是局部变量"
    print(f"函数内访问局部变量:{local_var}")
    print(f"函数内访问全局变量:{global_var}")
    
    # 尝试修改全局变量(实际上创建了新的局部变量)
    global_var = "尝试修改全局变量"  # 这创建了一个新的局部变量
    print(f"函数内修改后的变量:{global_var}")

test_scope()
print(f"函数外访问全局变量:{global_var}")  # 全局变量未被修改
print(f"函数外访问局部变量会报错")  # NameError: name 'local_var' is not defined

3.2 global 与 nonlocal 关键字

global 关键字
count = 0  # 全局变量

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

increment()  # 输出:当前计数:1
increment()  # 输出:当前计数:2
print(f"最终计数:{count}")  # 输出:最终计数:2
nonlocal 关键字
def outer():
    x = "outer"
    
    def inner():
        nonlocal x  # 声明使用外层函数的变量
        x = "inner"
        print(f"inner函数内:{x}")
    
    inner()
    print(f"outer函数内:{x}")

outer()
# 输出:
# inner函数内:inner
# outer函数内:inner

3.3 globals() 与 locals() 函数

# 全局命名空间
global_var = "global value"

def show_namespaces():
    # 局部变量
    local_var = "local value"
    another_local = 100
    
    print("=== 局部命名空间 ===")
    local_vars = locals()
    for key, value in local_vars.items():
        print(f"{key}: {value}")
    
    print("\n=== 全局命名空间(部分)===")
    # 只显示我们定义的全局变量
    global_vars = globals()
    for key in ['global_var', 'show_namespaces']:
        if key in global_vars:
            print(f"{key}: {global_vars[key]}")

show_namespaces()

4. 高级函数特性

4.1 匿名函数(lambda)

# 基本语法:lambda 参数: 表达式
add = lambda x, y: x + y
print(add(3, 5))  # 输出:8

# 常用场景1:作为参数传递给高阶函数
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x ** 2, numbers))
print(f"平方列表:{squared}")  # 输出:[1, 4, 9, 16, 25]

# 常用场景2:排序
students = [
    {"name": "Alice", "score": 85},
    {"name": "Bob", "score": 92},
    {"name": "Charlie", "score": 78}
]

# 按分数排序
sorted_students = sorted(students, key=lambda s: s["score"], reverse=True)
print("按分数排序:")
for student in sorted_students:
    print(f"{student['name']}: {student['score']}")

# 常用场景3:简单条件判断
is_even = lambda x: x % 2 == 0
print(f"4是偶数吗?{is_even(4)}")  # 输出:True
print(f"7是偶数吗?{is_even(7)}")  # 输出:False

4.2 高阶函数

高阶函数是指可以接收函数作为参数,或者返回函数作为结果的函数。

# 1. 接收函数作为参数
def apply_operation(numbers, operation):
    """对列表中的每个元素应用操作"""
    return [operation(x) for x in numbers]

def double(x):
    return x * 2

def square(x):
    return x ** 2

numbers = [1, 2, 3, 4, 5]
print(f"加倍:{apply_operation(numbers, double)}")    # 输出:[2, 4, 6, 8, 10]
print(f"平方:{apply_operation(numbers, square)}")    # 输出:[1, 4, 9, 16, 25]

# 2. 返回函数作为结果
def make_multiplier(factor):
    """创建乘法器函数"""
    def multiplier(x):
        return x * factor
    return multiplier

double_func = make_multiplier(2)
triple_func = make_multiplier(3)

print(f"double_func(5): {double_func(5)}")  # 输出:10
print(f"triple_func(5): {triple_func(5)}")  # 输出:15

# 3. 内置高阶函数示例
from functools import reduce

# map: 对每个元素应用函数
words = ["hello", "world", "python"]
lengths = list(map(len, words))
print(f"单词长度:{lengths}")  # 输出:[5, 5, 6]

# filter: 过滤元素
numbers = range(1, 11)
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(f"偶数:{even_numbers}")  # 输出:[2, 4, 6, 8, 10]

# reduce: 累积计算
product = reduce(lambda x, y: x * y, [1, 2, 3, 4, 5])
print(f"1-5的乘积:{product}")  # 输出:120

4.3 递归函数

递归函数是直接或间接调用自身的函数。

# 示例1:计算阶乘
def factorial(n):
    """计算n的阶乘(递归实现)"""
    if n == 0 or n == 1:
        return 1
    else:
        return n * factorial(n - 1)

print(f"5的阶乘:{factorial(5)}")  # 输出:120
print(f"10的阶乘:{factorial(10)}")  # 输出:3628800

# 示例2:斐波那契数列
def fibonacci(n):
    """计算第n个斐波那契数"""
    if n <= 0:
        return 0
    elif n == 1:
        return 1
    else:
        return fibonacci(n - 1) + fibonacci(n - 2)

print("斐波那契数列前10项:")
for i in range(1, 11):
    print(fibonacci(i), end=" ")  # 输出:1 1 2 3 5 8 13 21 34 55

# 示例3:目录树遍历(模拟)
def traverse_tree(node, depth=0):
    """递归遍历树形结构"""
    indent = "  " * depth
    print(f"{indent}{node['name']}")
    
    for child in node.get('children', []):
        traverse_tree(child, depth + 1)

# 模拟树结构
tree = {
    "name": "根节点",
    "children": [
        {
            "name": "子节点1",
            "children": [
                {"name": "孙节点1-1"},
                {"name": "孙节点1-2"}
            ]
        },
        {
            "name": "子节点2",
            "children": [
                {"name": "孙节点2-1"},
                {"name": "孙节点2-2", "children": [{"name": "曾孙节点"}]}
            ]
        }
    ]
}

print("\n树结构遍历:")
traverse_tree(tree)

5. 闭包与装饰器

5.1 闭包(Closure)

闭包是指在一个内部函数中,对外部作用域(非全局作用域)的变量进行引用。

def outer_function(msg):
    """外部函数"""
    message = msg
    
    def inner_function():
        """内部函数(闭包)"""
        print(f"消息:{message}")
    
    return inner_function  # 返回内部函数,而不是调用它

# 创建闭包
hello_func = outer_function("Hello")
bye_func = outer_function("Goodbye")

# 调用闭包函数
hello_func()  # 输出:消息:Hello
bye_func()    # 输出:消息:Goodbye

# 闭包的实际应用:计数器
def make_counter():
    """创建计数器闭包"""
    count = 0
    
    def counter():
        nonlocal count
        count += 1
        return count
    
    return counter

# 创建两个独立的计数器
counter1 = make_counter()
counter2 = make_counter()

print(f"计数器1: {counter1()}")  # 输出:1
print(f"计数器1: {counter1()}")  # 输出:2
print(f"计数器2: {counter2()}")  # 输出:1
print(f"计数器1: {counter1()}")  # 输出:3

5.2 装饰器(Decorator)

装饰器是一种特殊类型的闭包,用于修改或增强函数的行为。

# 1. 基本装饰器
def simple_decorator(func):
    """简单的装饰器"""
    def wrapper():
        print("=== 函数执行前 ===")
        result = func()
        print("=== 函数执行后 ===")
        return result
    return wrapper

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

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

# 2. 带参数的装饰器
def repeat(n):
    """重复执行n次的装饰器"""
    def decorator(func):
        def wrapper(*args, **kwargs):
            results = []
            for i in range(n):
                print(f"第{i+1}次执行:")
                result = func(*args, **kwargs)
                results.append(result)
            return results
        return wrapper
    return decorator

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

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

# 3. 保留函数元信息的装饰器
fro
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐