前言

Python 中函数分为具名函数(def)和匿名函数(lambda

1. 函数基本语法

函数定义与调用

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

    # 调用函数
    result = function_name(arguments)
基础示例
    def greet(name):
        """返回问候语"""
        return f"Hello, {name}!"

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

2. 参数类型详解

2.1 位置参数

def introduce(name, age, city):
    """位置参数:必须按顺序传递"""
    return f"{name} is {age} years old and lives in {city}."

print(introduce("Alice", 25, "Beijing"))
# 输出: Alice is 25 years old and lives in Beijing.

2.2 默认参数

def greet_person(name, greeting="Hello", punctuation="!"):
    """默认参数:调用时可省略"""
    return f"{greeting}, {name}{punctuation}"

print(greet_person("Bob"))                # 输出: Hello, Bob!
print(greet_person("Charlie", "Hi"))      # 输出: Hi, Charlie!
print(greet_person("David", "Hey", "."))  # 输出: Hey, David.

注意事项:

# 错误:默认参数必须是不可变对象
def bad_function(arg=[]):  # 危险!
    arg.append(1)
    return arg

# 正确:使用None作为默认值
def good_function(arg=None):
    if arg is None:
        arg = []
    arg.append(1)
    return arg

2.3 关键字参数

def create_profile(name, age, city, country="China"):
    """关键字参数:按参数名传递"""
    return f"{name}, {age}, from {city}, {country}"

# 多种调用方式
print(create_profile("Alice", 25, "Beijing"))
print(create_profile(name="Bob", age=30, city="Shanghai"))
print(create_profile(city="Guangzhou", name="Charlie", age=28))

2.4 可变参数 *args

    def sum_numbers(*args):
        """*args 接收任意数量的位置参数,作为元组处理"""
        print(f"参数类型: {type(args)}")  # <class 'tuple'>
        return sum(args)

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

2.5 关键字可变参数 **kwargs

    def print_profile(**kwargs):
        """**kwargs 接收任意数量的关键字参数,作为字典处理"""
        print(f"参数类型: {type(kwargs)}")  # <class 'dict'>
        for key, value in kwargs.items():
            print(f"{key}: {value}")

    print_profile(name="Alice", age=25, city="Beijing")
    # 输出:
    # name: Alice
    # age: 25
    # city: Beijing

2.6 参数组合使用

    def complex_function(a, b, *args, c=10, d=20, **kwargs):
        """完整的参数顺序:位置参数 -> *args -> 默认参数 -> **kwargs"""
        print(f"a: {a}, b: {b}")
        print(f"args: {args}")
        print(f"c: {c}, d: {d}")
        print(f"kwargs: {kwargs}")

    complex_function(1, 2, 3, 4, c=30, name="Alice", age=25)
    # 输出:
    # a: 1, b: 2
    # args: (3, 4)
    # c: 30, d: 20
    # kwargs: {'name': 'Alice', 'age': 25}

3. 特殊参数类型(Python 3.8+)

3.1 仅位置参数

    def position_only(a, b, /, c):
        """/ 前的参数只能按位置传递"""
        return a + b + c

    print(position_only(1, 2, 3))     # 正确
    print(position_only(1, 2, c=3))   # 正确
    # position_only(a=1, b=2, c=3)    # 错误:a, b不能使用关键字

3.2 仅关键字参数

    def keyword_only(a, b, *, c, d):
        """* 后的参数只能按关键字传递"""
        return a + b + c + d

    print(keyword_only(1, 2, c=3, d=4))     # 正确
    # keyword_only(1, 2, 3, 4)              # 错误:c, d必须使用关键字

3.3 混合使用

    def comprehensive(a, b, /, c, d, *, e, f):
        """位置参数 / 普通参数 * 关键字参数"""
        return a + b + c + d + e + f

    print(comprehensive(1, 2, 3, d=4, e=5, f=6))  # 正确

4. 函数注解(Type Hints)

    def annotated_function(
        name: str, 
        age: int, 
        *scores: float, 
        city: str = "Beijing", 
        **kwargs: str
    ) -> str:
        """
        函数注解:提供类型提示,不影响运行时
        """
        avg_score = sum(scores) / len(scores) if scores else 0
        return f"{name}, {age}, from {city}, average score: {avg_score:.2f}"

    # 使用示例
    result = annotated_function("Alice", 25, 85.5, 92.0, 78.5, city="Shanghai", major="CS")
    print(result)

5. 返回值详解

多返回值

    def analyze_numbers(numbers):
        """返回多个值(实际上是返回元组)"""
        if not numbers:
            return 0, 0, 0
        
        total = sum(numbers)
        average = total / len(numbers)
        maximum = max(numbers)
        
        return total, average, maximum  # 返回元组

    # 接收多个返回值
    total, avg, max_val = analyze_numbers([1, 2, 3, 4, 5])
    print(f"总和: {total}, 平均: {avg}, 最大值: {max_val}")

返回函数(闭包)

    def multiplier(factor):
        """返回一个函数(闭包)"""
        def multiply(x):
            return x * factor
        return multiply

    double = multiplier(2)
    triple = multiplier(3)

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

6. 高级函数特性

6.1 递归函数

    def factorial(n):
        """递归计算阶乘"""
        if n == 0 or n == 1:
            return 1
        else:
            return n * factorial(n - 1)

    print(factorial(5))  # 输出: 120

6.2 生成器函数

    def fibonacci_sequence(limit):
        """生成器函数:生成斐波那契数列"""
        a, b = 0, 1
        while a < limit:
            yield a
            a, b = b, a + b

    # 使用生成器
    for num in fibonacci_sequence(100):
        print(num, end=" ")
    # 输出: 0 1 1 2 3 5 8 13 21 34 55 89

6.3 装饰器函数

    def timer_decorator(func):
        """计时装饰器"""
        def wrapper(*args, **kwargs):
            import time
            start = time.time()
            result = func(*args, **kwargs)
            end = time.time()
            print(f"函数 {func.__name__} 执行时间: {end - start:.4f}秒")
            return result
        return wrapper

    @timer_decorator
    def slow_function():
        """被装饰的函数"""
        import time
        time.sleep(1)
        return "完成"

    print(slow_function())

7. 作用域规则

    global_var = "全局变量"

    def scope_demo():
        local_var = "局部变量"
        print(f"函数内访问全局变量: {global_var}")
        print(f"函数内访问局部变量: {local_var}")
        
        def inner_function():
            inner_var = "内部变量"
            nonlocal local_var  # 修改外部函数的变量
            local_var = "修改后的局部变量"
            print(f"内部函数访问: {local_var}")
        
        inner_function()
        print(f"外部函数看到: {local_var}")

    scope_demo()

8. 最佳实践总结

命名规范:使用小写字母和下划线,动词开头
单一职责:一个函数只做一件事
文档字符串:为复杂函数添加文档
参数设计:合理使用默认参数和类型提示
错误处理:在函数内处理可能的异常
保持简洁:函数体不宜过长

def calculate_grade(scores: list[float]) -> dict[str, float]:
    """
    计算学生成绩统计信息
    
    Args:
        scores: 分数列表
        
    Returns:
        包含各种统计信息的字典
    """
    if not scores:
        raise ValueError("分数列表不能为空")
    
    return {
        'average': sum(scores) / len(scores),
        'max': max(scores),
        'min': min(scores),
        'count': len(scores)
    }

# 使用示例
try:
    result = calculate_grade([85, 92, 78, 96, 88])
    print(result)
except ValueError as e:
    print(f"错误: {e}")

9. 使用建议

使用def的情况:

复杂逻辑或多行代码
需要重复使用的函数
需要文档字符串和类型注解的函数

使用lambda的情况:

简单的单行操作
作为参数传递给高阶函数
临时使用的回调函数
代码可读性优先:

    # 好的实践
    numbers = [1, 2, 3, 4, 5]

    # 清晰易懂的lambda
    doubled = list(map(lambda x: x * 2, numbers))

    # 如果逻辑复杂,使用def
    def complex_calculation(x):
        """执行复杂计算"""
        # 多行逻辑...
        return result

通过合理使用def和lambda,可读性通常比简洁性更重要

Logo

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

更多推荐