本文全面解析 Python 函数的定义、参数、返回值、作用域及高级特性,配合丰富示例代码


目录

  1. 函数基础
  2. 参数详解
  3. 返回值
  4. 变量作用域
  5. 匿名函数(Lambda)
  6. 高阶函数
  7. 装饰器
  8. 递归函数
  9. 生成器函数
  10. 闭包

1. 函数基础

1.1 定义函数

使用 def 关键字定义函数,函数名后接圆括号和冒号

def greet():
    """这是一个简单的问候函数"""
    print("Hello, Python!")

greet()  # 输出: Hello, Python!

1.2 函数文档字符串(Docstring)

def calculate_area(length, width):
    """
    计算矩形的面积

    参数:
        length (float): 矩形的长度
        width (float): 矩形的宽度

    返回:
        float: 矩形的面积
    """
    return length * width

# 查看文档
print(calculate_area.__doc__)

1.3 函数是对象

def say_hello():
    print("Hello!")

# 函数可以赋值给变量
my_func = say_hello
my_func()  # 输出: Hello!

# 函数可以存储在数据结构中
functions = [say_hello, lambda: print("Hi!")]
functions[0]()  # 输出: Hello!

2. 参数详解

2.1 位置参数

def introduce(name, age):
    print(f"我叫{name},今年{age}岁。")

introduce("张三", 25)  # 输出: 我叫张三,今年25岁。

2.2 默认参数

def create_user(username, role="user", active=True):
    print(f"用户名: {username}, 角色: {role}, 状态: {'激活' if active else '禁用'}")

create_user("admin")                    # 用户名: admin, 角色: user, 状态: 激活
create_user("manager", "admin")         # 用户名: manager, 角色: admin, 状态: 激活
create_user("test", active=False)       # 用户名: test, 角色: user, 状态: 禁用

⚠️ 警告:默认参数不要使用可变对象(如列表、字典),因为默认值在函数定义时只创建一次

# 错误示例
def add_item_wrong(item, items=[]):
    items.append(item)
    return items

print(add_item_wrong(1))  # [1]
print(add_item_wrong(2))  # [1, 2]  ← 意外保留了之前的数据!

# 正确示例
def add_item_correct(item, items=None):
    if items is None:
        items = []
    items.append(item)
    return items

print(add_item_correct(1))  # [1]
print(add_item_correct(2))  # [2]  ← 每次都是新的列表

2.3 关键字参数

def book_flight(origin, destination, date, class_type="经济舱"):
    print(f"{origin} → {destination},日期: {date},舱位: {class_type}")

# 使用关键字参数,顺序可以打乱
book_flight(destination="北京", origin="上海", date="2024-05-01")
# 输出: 上海 → 北京,日期: 2024-05-01,舱位: 经济舱

2.4 可变参数 *args

def calculate_sum(*numbers):
    """接收任意数量的位置参数,以元组形式存储"""
    total = 0
    for num in numbers:
        total += num
    return total

print(calculate_sum(1, 2, 3))      # 6
print(calculate_sum())              # 0
print(calculate_sum(10, 20))        # 30

# 解包传递
data = [1, 2, 3, 4, 5]
print(calculate_sum(*data))         # 15

2.5 可变关键字参数 **kwargs

def build_profile(**kwargs):
    """接收任意数量的关键字参数,以字典形式存储"""
    profile = {}
    for key, value in kwargs.items():
        profile[key] = value
    return profile

user = build_profile(name="李四", age=30, city="深圳", hobby="编程")
print(user)
# 输出: {'name': '李四', 'age': 30, 'city': '深圳', 'hobby': '编程'}

# 解包传递
info = {"name": "王五", "job": "工程师"}
print(build_profile(**info, salary=15000))
# 输出: {'name': '王五', 'job': '工程师', 'salary': 15000}

2.6 参数顺序规则

def complex_function(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2, **kwargs):
    """
    参数顺序:
    1. 仅限位置参数 (/) 之前
    2. 位置或关键字参数 (/) 和 (*) 之间
    3. 仅限关键字参数 (*) 之后
    4. **kwargs 最后
    """
    print(f"pos1={pos1}, pos2={pos2}, pos_or_kwd={pos_or_kwd}")
    print(f"kwd1={kwd1}, kwd2={kwd2}, kwargs={kwargs}")

complex_function(1, 2, 3, kwd1="a", kwd2="b", extra="c")
# pos1=1, pos2=2, pos_or_kwd=3
# kwd1=a, kwd2=b, kwargs={'extra': 'c'}

2.7 类型注解(Type Hints)

from typing import List, Dict, Optional

def process_data(items: List[int], config: Optional[Dict[str, str]] = None) -> int:
    """
    items: 整数列表
    config: 可选的配置字典
    返回: 整数结果
    """
    if config is None:
        config = {}
    multiplier = int(config.get("multiplier", "1"))
    return sum(items) * multiplier

result = process_data([1, 2, 3], {"multiplier": "2"})
print(result)  # 12

3. 返回值

3.1 返回单个值

import math

def circle_properties(radius):
    area = math.pi * radius ** 2
    return area

print(circle_properties(5))  # 78.53981633974483

3.2 返回多个值(元组解包)

def get_min_max(numbers):
    """同时返回最小值和最大值"""
    return min(numbers), max(numbers)

minimum, maximum = get_min_max([3, 1, 4, 1, 5, 9, 2, 6])
print(f"最小值: {minimum}, 最大值: {maximum}")
# 输出: 最小值: 1, 最大值: 9

3.3 没有 return 语句

def print_message(msg):
    print(msg)
    # 没有 return,默认返回 None

result = print_message("测试")
print(result)  # None

3.4 条件返回

def check_number(n):
    if n > 0:
        return "正数"
    elif n < 0:
        return "负数"
    else:
        return "零"

print(check_number(10))   # 正数
print(check_number(-5))   # 负数
print(check_number(0))    # 零

4. 变量作用域

4.1 LEGB 规则

Python 查找变量的顺序:Local → Enclosing → Global → Built-in

x = "global"  # 全局变量

def outer():
    x = "enclosing"  # 嵌套作用域变量

    def inner():
        x = "local"  # 局部变量
        print(f"inner: {x}")  # local

    inner()
    print(f"outer: {x}")  # enclosing

outer()
print(f"global: {x}")  # global

4.2 global 关键字

counter = 0

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

increment()  # 计数器: 1
increment()  # 计数器: 2
print(f"最终值: {counter}")  # 最终值: 2

4.3 nonlocal 关键字

def make_counter():
    count = 0

    def increment():
        nonlocal count  # 修改嵌套作用域的变量
        count += 1
        return count

    return increment

counter = make_counter()
print(counter())  # 1
print(counter())  # 2
print(counter())  # 3

5. 匿名函数(Lambda)

5.1 基本语法

# 普通函数
def square(x):
    return x ** 2

# 等价的 lambda 函数
square_lambda = lambda x: x ** 2

print(square(5))         # 25
print(square_lambda(5))  # 25

5.2 常见应用场景

# 排序
students = [("张三", 85), ("李四", 92), ("王五", 78)]
students.sort(key=lambda x: x[1], reverse=True)
print(students)  # [('李四', 92), ('张三', 85), ('王五', 78)]

# map 函数
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x ** 2, numbers))
print(squared)  # [1, 4, 9, 16, 25]

# filter 函数
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens)  # [2, 4]

# reduce 函数
from functools import reduce
product = reduce(lambda x, y: x * y, numbers)
print(product)  # 120

5.3 多参数 Lambda

# 两个参数
add = lambda x, y: x + y
print(add(3, 5))  # 8

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

6. 高阶函数

6.1 函数作为参数

def apply_operation(numbers, operation):
    """接收一个函数作为参数"""
    return [operation(n) for n in numbers]

def double(x):
    return x * 2

def triple(x):
    return x * 3

nums = [1, 2, 3, 4]
print(apply_operation(nums, double))  # [2, 4, 6, 8]
print(apply_operation(nums, triple))  # [3, 6, 9, 12]
print(apply_operation(nums, lambda x: x ** 2))  # [1, 4, 9, 16]

6.2 函数作为返回值

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

double = make_multiplier(2)
triple = make_multiplier(3)

print(double(5))   # 10
print(triple(5))   # 15

6.3 内置高阶函数

# map - 映射
names = ["alice", "bob", "charlie"]
capitalized = list(map(str.capitalize, names))
print(capitalized)  # ['Alice', 'Bob', 'Charlie']

# filter - 过滤
scores = [55, 70, 85, 90, 45, 60]
passed = list(filter(lambda x: x >= 60, scores))
print(passed)  # [70, 85, 90, 60]

# sorted - 排序
words = ["banana", "pie", "Washington", "book"]
by_length = sorted(words, key=len)
print(by_length)  # ['pie', 'book', 'banana', 'Washington']

7. 装饰器

7.1 简单装饰器

import time

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

@timer
def slow_function():
    time.sleep(1)
    return "Done"

result = slow_function()
# 输出: slow_function 执行时间: 1.00xx秒

7.2 带参数的装饰器

def repeat(times):
    """接收参数的装饰器"""
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(times):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator

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

greet("Python")
# 输出:
# Hello, Python!
# Hello, Python!
# Hello, Python!

7.3 保留元信息的装饰器

from functools import wraps

def my_decorator(func):
    @wraps(func)  # 保留原函数的元信息
    def wrapper(*args, **kwargs):
        print("装饰器执行前")
        result = func(*args, **kwargs)
        print("装饰器执行后")
        return result
    return wrapper

@my_decorator
def example():
    """示例函数"""
    print("函数主体")

print(example.__name__)  # example(不是 wrapper)
print(example.__doc__)   # 示例函数

7.4 类装饰器

class CountCalls:
    """统计函数调用次数的类装饰器"""
    def __init__(self, func):
        self.func = func
        self.count = 0

    def __call__(self, *args, **kwargs):
        self.count += 1
        print(f"第 {self.count} 次调用")
        return self.func(*args, **kwargs)

@CountCalls
def say_hi():
    print("Hi!")

say_hi()  # 第 1 次调用
say_hi()  # 第 2 次调用
say_hi()  # 第 3 次调用

8. 递归函数

8.1 阶乘计算

def factorial(n):
    """计算 n 的阶乘"""
    if n <= 1:
        return 1
    return n * factorial(n - 1)

print(factorial(5))   # 120
print(factorial(10))  # 3628800

8.2 斐波那契数列

def fibonacci(n):
    """返回第 n 个斐波那契数"""
    if n <= 1:
        return n
    return fibonacci(n - 1) + fibonacci(n - 2)

# 打印前 10 个斐波那契数
for i in range(10):
    print(fibonacci(i), end=" ")
# 输出: 0 1 1 2 3 5 8 13 21 34

8.3 尾递归优化(模拟)

def factorial_tail(n, accumulator=1):
    """尾递归风格的阶乘(Python 不优化尾递归,但代码风格如此)"""
    if n <= 1:
        return accumulator
    return factorial_tail(n - 1, n * accumulator)

print(factorial_tail(5))  # 120

8.4 递归深度限制

import sys

print(f"默认递归深度限制: {sys.getrecursionlimit()}")
# 默认通常是 1000

# 可以修改(谨慎使用)
# sys.setrecursionlimit(2000)

9. 生成器函数

9.1 使用 yield

def countdown(n):
    """从 n 倒数到 1"""
    while n > 0:
        yield n
        n -= 1

# 使用生成器
counter = countdown(5)
for num in counter:
    print(num, end=" ")
# 输出: 5 4 3 2 1

9.2 生成器表达式

# 列表推导式(一次性生成所有数据)
squares_list = [x**2 for x in range(1000000)]  # 占用大量内存

# 生成器表达式(惰性求值)
squares_gen = (x**2 for x in range(1000000))   # 几乎不占用内存

# 按需获取
print(next(squares_gen))  # 0
print(next(squares_gen))  # 1

9.3 斐波那契生成器

def fibonacci_generator(limit):
    """生成斐波那契数列,直到达到限制"""
    a, b = 0, 1
    while a < limit:
        yield a
        a, b = b, a + b

for num in fibonacci_generator(100):
    print(num, end=" ")
# 输出: 0 1 1 2 3 5 8 13 21 34 55 89

9.4 yield from(Python 3.3+)

def sub_generator():
    yield 1
    yield 2

def main_generator():
    yield "开始"
    yield from sub_generator()  # 委托子生成器
    yield "结束"

for item in main_generator():
    print(item)
# 输出:
# 开始
# 1
# 2
# 结束

10. 闭包

10.1 基本概念

闭包是指引用了外部作用域变量的函数,即使外部函数已经执行完毕

def make_power(exponent):
    """创建求幂函数"""
    def power(base):
        return base ** exponent
    return power

square = make_power(2)
cube = make_power(3)

print(square(4))  # 16
print(cube(3))    # 27

10.2 闭包与状态保持

def make_averager():
    """创建平均值计算器,保持历史数据"""
    numbers = []

    def averager(value):
        numbers.append(value)
        return sum(numbers) / len(numbers)

    return averager

avg = make_averager()
print(avg(10))   # 10.0
print(avg(20))   # 15.0
print(avg(30))   # 20.0

10.3 闭包与 nonlocal

def make_counter():
    count = 0

    def counter():
        nonlocal count
        count += 1
        return count

    # 查看闭包变量
    counter.get_count = lambda: count
    return counter

c = make_counter()
print(c())         # 1
print(c())         # 2
print(c.get_count())  # 2

10.4 闭包 vs 类

# 使用闭包实现简单计数器
def counter_closure():
    count = [0]  # 使用可变对象避免 nonlocal
    def increment():
        count[0] += 1
        return count[0]
    return increment

# 使用类实现相同功能
class CounterClass:
    def __init__(self):
        self.count = 0
    def increment(self):
        self.count += 1
        return self.count

# 两者功能相同
closure_counter = counter_closure()
class_counter = CounterClass()

print(closure_counter())  # 1
print(class_counter.increment())  # 1

附录:函数速查表

特性语法示例
定义函数def name():def foo(): pass
默认参数def name(arg=val)def foo(x=1):
可变位置参数*argsdef foo(*args):
可变关键字参数**kwargsdef foo(**kwargs):
仅限位置参数/def foo(x, /):
仅限关键字参数*def foo(*, x):
Lambdalambda args: exprlambda x: x**2
装饰器@decorator@timer
生成器yielddef gen(): yield 1
类型注解arg: typedef foo(x: int) -> str:

学习建议

  1. 从基础函数定义开始,逐步掌握参数传递
  2. 理解作用域规则是避免 bug 的关键
  3. 装饰器和生成器是 Python 高级编程的核心
  4. 多写代码,多调试,才能真正掌握函数精髓

 

Logo

这里是“一人公司”的成长家园。我们提供从产品曝光、技术变现到法律财税的全栈内容,并连接云服务、办公空间等稀缺资源,助你专注创造,无忧运营。

更多推荐