1.10 Python 函数定义与参数传递
前言:函数化编程的重要性
在前九篇文章中,我们系统学习了Python的基本语法、数据类型、控制结构、文件操作以及数据结构。现在,我们将深入探讨Python编程中最为重要的概念之一——函数。函数是组织代码的基本单元,它们允许我们将代码分解为可重用的块,提高代码的可读性、可维护性和复用性。
函数不仅是代码组织的工具,更是抽象思维的体现。通过函数,我们可以将复杂问题分解为更小、更易管理的部分,每个部分都有明确的输入和输出。本文将深入探讨Python函数的定义、参数传递机制以及高级函数特性,通过丰富的实战案例,帮助你掌握函数编程的精髓。
一、 函数基础:定义与调用
函数是一段可重用的代码块,它接受输入(参数),执行特定任务,并返回结果。
1.1 函数的基本结构
语法结构:
def function_name(parameters):
"""文档字符串(可选)"""
# 函数体
statement1
statement2
...
return result # 可选
实战案例10-1:基本函数定义与调用
# 定义一个简单的函数
def greet():
"""打印问候语"""
print("Hello, World!")
# 调用函数
greet() # 输出: Hello, World!
# 带参数的函数
def greet_person(name):
"""向指定的人问候"""
print(f"Hello, {name}!")
greet_person("Alice") # 输出: Hello, Alice!
greet_person("Bob") # 输出: Hello, Bob!
# 带返回值的函数
def add_numbers(a, b):
"""返回两个数的和"""
return a + b
result = add_numbers(5, 3)
print(f"5 + 3 = {result}") # 输出: 5 + 3 = 8
# 多个返回值的函数(实际上返回元组)
def get_name_and_age():
"""返回姓名和年龄"""
return "Alice", 25 # 实际上是返回一个元组
name, age = get_name_and_age() # 元组解包
print(f"Name: {name}, Age: {age}") # 输出: Name: Alice, Age: 25
# 无返回值的函数实际上返回None
def do_nothing():
"""什么都不做"""
pass
result = do_nothing()
print(f"无返回值函数的返回结果: {result}") # 输出: 无返回值函数的返回结果: None
1.2 文档字符串(Docstring)
文档字符串是函数的第一条语句,用于描述函数的功能、参数和返回值。
实战案例10-2:文档字符串的使用
def calculate_circle_area(radius):
"""
计算圆的面积
参数:
radius (float): 圆的半径,必须为非负数
返回:
float: 圆的面积
抛出:
ValueError: 如果半径为负数
"""
if radius < 0:
raise ValueError("半径不能为负数")
return 3.14159 * radius ** 2
# 查看文档字符串
print(calculate_circle_area.__doc__)
# 使用help函数查看文档
help(calculate_circle_area)
# 测试函数
try:
area = calculate_circle_area(5)
print(f"半径为5的圆面积: {area:.2f}") # 输出: 半径为5的圆面积: 78.54
area = calculate_circle_area(-2) # 会抛出异常
except ValueError as e:
print(f"错误: {e}") # 输出: 错误: 半径不能为负数
1.3 函数的作用域
Python中有四种作用域:
- 局部作用域(Local):函数内部
- 闭包函数外的函数作用域(Enclosing):嵌套函数的外部函数
- 全局作用域(Global):模块级别
- 内置作用域(Built-in):Python内置名称
实战案例10-3:作用域解析
# 全局变量
global_var = "我是全局变量"
def test_scope():
# 局部变量
local_var = "我是局部变量"
print(f"函数内部 - 局部变量: {local_var}")
print(f"函数内部 - 全局变量: {global_var}")
# 尝试修改全局变量(实际上会创建新的局部变量)
global_var = "我试图修改全局变量" # 这实际上是创建了一个新的局部变量
print(f"函数内部 - 修改后的变量: {global_var}")
def inner_function():
# 内部函数可以访问外部函数的变量
print(f"内部函数 - 外部函数的变量: {local_var}")
print(f"内部函数 - 全局变量: {global_var}")
inner_function()
test_scope()
print(f"函数外部 - 全局变量: {global_var}") # 全局变量没有被修改
# 使用global关键字修改全局变量
def modify_global():
global global_var # 声明使用全局变量
global_var = "我真的修改了全局变量"
print(f"函数内部 - 修改后的全局变量: {global_var}")
modify_global()
print(f"函数外部 - 修改后的全局变量: {global_var}") # 全局变量被修改了
# 使用nonlocal关键字修改嵌套作用域的变量
def outer_function():
outer_var = "外部函数变量"
def inner_function():
nonlocal outer_var # 声明使用外部函数的变量
outer_var = "内部函数修改了外部变量"
print(f"内部函数 - 修改后的变量: {outer_var}")
inner_function()
print(f"外部函数 - 修改后的变量: {outer_var}")
outer_function()
二、 参数传递:位置参数与默认参数
Python支持多种参数传递方式,使函数调用更加灵活。
2.1 位置参数(Positional Arguments)
位置参数是按照定义时的顺序传递的参数。
实战案例10-4:位置参数的使用
def describe_pet(animal_type, pet_name):
"""显示宠物信息"""
print(f"I have a {animal_type}.")
print(f"My {animal_type}'s name is {pet_name}.")
# 按位置传递参数
describe_pet("dog", "Willie") # 正确顺序
describe_pet("Willie", "dog") # 错误顺序,但语法正确,语义错误
# 多次调用函数
describe_pet("hamster", "Harry")
describe_pet("cat", "Whiskers")
# 带有更多参数的函数
def build_profile(first, last, age, city):
"""构建用户资料字典"""
profile = {
"first_name": first,
"last_name": last,
"age": age,
"city": city
}
return profile
user_profile = build_profile("Alice", "Smith", 25, "New York")
print(f"用户资料: {user_profile}")
2.2 默认参数(Default Arguments)
默认参数是在定义函数时指定默认值的参数,调用时可以省略。
实战案例10-5:默认参数的使用
def describe_pet(pet_name, animal_type="dog"):
"""显示宠物信息(带有默认参数)"""
print(f"I have a {animal_type}.")
print(f"My {animal_type}'s name is {pet_name}.")
# 使用默认参数
describe_pet("Willie") # 使用默认的animal_type="dog"
describe_pet("Harry", "hamster") # 提供animal_type参数
# 多个默认参数
def make_shirt(size="large", message="I love Python"):
"""制作T恤"""
print(f"Making a {size} shirt with the message: '{message}'")
make_shirt() # 使用所有默认值
make_shirt("medium") # 提供size,使用默认message
make_shirt(message="Hello World") # 使用默认size,提供message
make_shirt("small", "Coding is fun!") # 提供所有参数
# 默认参数的注意事项
def add_to_list(value, my_list=[]):
"""向列表添加元素(有问题的实现)"""
my_list.append(value)
return my_list
# 默认参数在函数定义时计算,而不是每次调用时
result1 = add_to_list(1)
print(f"第一次调用: {result1}") # [1]
result2 = add_to_list(2)
print(f"第二次调用: {result2}") # [1, 2] - 这不是我们期望的!
# 正确的实现方式
def add_to_list_correct(value, my_list=None):
"""向列表添加元素(正确的实现)"""
if my_list is None:
my_list = []
my_list.append(value)
return my_list
result1 = add_to_list_correct(1)
print(f"第一次调用: {result1}") # [1]
result2 = add_to_list_correct(2)
print(f"第二次调用: {result2}") # [2] - 这才是我们期望的!
2.3 关键字参数(Keyword Arguments)
关键字参数是通过参数名传递的参数,可以不按照定义顺序。
实战案例10-6:关键字参数的使用
def describe_pet(animal_type, pet_name):
"""显示宠物信息"""
print(f"I have a {animal_type}.")
print(f"My {animal_type}'s name is {pet_name}.")
# 使用关键字参数
describe_pet(animal_type="hamster", pet_name="Harry")
describe_pet(pet_name="Willie", animal_type="dog") # 顺序不重要
# 混合使用位置参数和关键字参数
describe_pet("cat", pet_name="Whiskers") # 位置参数必须在关键字参数之前
# 以下代码会报错
# describe_pet(animal_type="bird", "Polly") # 关键字参数后不能有位置参数
# 更复杂的例子
def create_user_profile(first_name, last_name, age=30, city="Unknown", country="Unknown"):
"""创建用户资料"""
profile = {
"first_name": first_name,
"last_name": last_name,
"age": age,
"city": city,
"country": country
}
return profile
# 使用关键字参数提供部分信息
profile1 = create_user_profile("Alice", "Smith", age=25, city="New York")
print(f"用户1资料: {profile1}")
# 使用关键字参数提供所有信息
profile2 = create_user_profile(
first_name="Bob",
last_name="Johnson",
age=35,
city="London",
country="UK"
)
print(f"用户2资料: {profile2}")
# 只提供必需参数
profile3 = create_user_profile("Charlie", "Brown")
print(f"用户3资料: {profile3}")
三、 高级参数传递:可变参数
Python支持可变数量的参数,使函数更加灵活。
*3.1 可变位置参数(args)
使用*args可以接收任意数量的位置参数。
实战案例10-7:可变位置参数的使用
def make_pizza(*toppings):
"""制作披萨,接受任意数量的配料"""
print("\nMaking a pizza with the following toppings:")
for topping in toppings:
print(f"- {topping}")
# 使用不同数量的参数调用函数
make_pizza("pepperoni")
make_pizza("mushrooms", "green peppers", "extra cheese")
# 与其他参数结合使用
def make_pizza_size(size, *toppings):
"""制作指定大小的披萨"""
print(f"\nMaking a {size} pizza with the following toppings:")
for topping in toppings:
print(f"- {topping}")
make_pizza_size("large", "pepperoni")
make_pizza_size("medium", "mushrooms", "olives", "onions")
# 使用*args收集剩余的位置参数
def print_args(arg1, arg2, *args):
"""演示*args的使用"""
print(f"第一个参数: {arg1}")
print(f"第二个参数: {arg2}")
print(f"其余参数: {args}") # 这是一个元组
print_args(1, 2, 3, 4, 5) # 输出: 第一个参数: 1, 第二个参数: 2, 其余参数: (3, 4, 5)
# 实际应用:计算任意数量的数字之和
def sum_numbers(*numbers):
"""计算任意数量的数字之和"""
total = 0
for num in numbers:
total += num
return total
print(f"1+2+3 = {sum_numbers(1, 2, 3)}") # 6
print(f"1+2+3+4+5 = {sum_numbers(1, 2, 3, 4, 5)}") # 15
print(f"空参数 = {sum_numbers()}") # 0
# 使用*运算符解包序列
numbers = [1, 2, 3, 4, 5]
print(f"列表求和: {sum_numbers(*numbers)}") # 15
tuple_numbers = (10, 20, 30)
print(f"元组求和: {sum_numbers(*tuple_numbers)}") # 60
**3.2 可变关键字参数(kwargs)
使用**kwargs可以接收任意数量的关键字参数。
实战案例10-8:可变关键字参数的使用
def build_profile(first, last, **user_info):
"""构建用户资料,接受任意数量的关键字参数"""
profile = {}
profile['first_name'] = first
profile['last_name'] = last
for key, value in user_info.items():
profile[key] = value
return profile
# 使用不同数量的关键字参数
user_profile = build_profile(
"albert",
"einstein",
location="princeton",
field="physics",
age=76
)
print(f"用户资料: {user_profile}")
# 与其他参数结合使用
def create_car(make, model, **car_info):
"""创建汽车信息"""
car = {"make": make, "model": model}
car.update(car_info)
return car
car = create_car(
"subaru",
"outback",
color="blue",
tow_package=True,
year=2023
)
print(f"汽车信息: {car}")
# 使用**kwargs收集剩余的关键字参数
def print_kwargs(arg1, arg2, **kwargs):
"""演示**kwargs的使用"""
print(f"第一个参数: {arg1}")
print(f"第二个参数: {arg2}")
print(f"关键字参数: {kwargs}") # 这是一个字典
print_kwargs(1, 2, name="Alice", age=25, city="New York")
# 实际应用:配置函数
def configure_app(**settings):
"""配置应用程序"""
default_settings = {
"debug": False,
"log_level": "INFO",
"max_connections": 100
}
# 更新默认设置
default_settings.update(settings)
return default_settings
# 使用不同配置
app_config = configure_app()
print(f"默认配置: {app_config}")
app_config = configure_app(debug=True, max_connections=200)
print(f"自定义配置: {app_config}")
# 使用**运算符解包字典
settings_dict = {"debug": True, "log_level": "DEBUG", "timeout": 30}
app_config = configure_app(**settings_dict)
print(f"字典解包配置: {app_config}")
3.3 综合使用所有参数类型
Python允许在函数定义中综合使用所有参数类型,但必须遵循特定顺序。
参数顺序规则:
- 位置参数
- 默认参数
- 可变位置参数(*args)
- 关键字-only参数(Python 3+)
- 可变关键字参数(**kwargs)
实战案例10-9:综合参数使用
def complex_function(a, b=10, *args, c=20, d=30, **kwargs):
"""
综合使用所有参数类型的复杂函数
参数:
a: 必需的位置参数
b: 有默认值的位置参数
*args: 可变位置参数
c: 关键字-only参数(有默认值)
d: 关键字-only参数(有默认值)
**kwargs: 可变关键字参数
"""
print(f"a = {a}")
print(f"b = {b}")
print(f"args = {args}")
print(f"c = {c}")
print(f"d = {d}")
print(f"kwargs = {kwargs}")
print("-" * 30)
# 测试各种调用方式
complex_function(1) # a=1, b=10, args=(), c=20, d=30, kwargs={}
complex_function(1, 2) # a=1, b=2, args=(), c=20, d=30, kwargs={}
complex_function(1, 2, 3, 4, 5) # a=1, b=2, args=(3,4,5), c=20, d=30, kwargs={}
complex_function(1, 2, 3, 4, 5, c=100, d=200) # a=1, b=2, args=(3,4,5), c=100, d=200, kwargs={}
complex_function(1, 2, 3, 4, 5, c=100, d=200, x=999, y=888) # a=1, b=2, args=(3,4,5), c=100, d=200, kwargs={'x':999,'y':888}
# 关键字-only参数(Python 3+)
def keyword_only_function(a, b, *, c, d):
"""使用关键字-only参数"""
print(f"a={a}, b={b}, c={c}, d={d}")
# 必须使用关键字传递c和d
keyword_only_function(1, 2, c=3, d=4) # 正确
# keyword_only_function(1, 2, 3, 4) # 错误:必须使用关键字参数
# 实际应用:灵活的数据库查询函数
def query_database(table, *columns, where=None, order_by=None, limit=100, **filters):
"""
模拟数据库查询函数
参数:
table: 表名(必需)
*columns: 要查询的列
where: WHERE条件(关键字-only)
order_by: 排序字段(关键字-only)
limit: 限制结果数量(关键字-only)
**filters: 其他过滤条件
"""
query = f"SELECT {', '.join(columns) if columns else '*'} FROM {table}"
conditions = []
if where:
conditions.append(where)
for key, value in filters.items():
conditions.append(f"{key} = {value}")
if conditions:
query += " WHERE " + " AND ".join(conditions)
if order_by:
query += f" ORDER BY {order_by}"
if limit:
query += f" LIMIT {limit}"
return query
# 使用各种参数组合进行查询
print(query_database("users", "id", "name", "email", where="age > 18", limit=10))
print(query_database("products", "name", "price", category="electronics", in_stock=True))
print(query_database("orders", where="status = 'completed'", order_by="created_at DESC", limit=50))
四、 函数高级特性
Python函数支持许多高级特性,如 lambda 函数、闭包和装饰器等。
4.1 Lambda 函数(匿名函数)
Lambda函数是一种简洁的定义简单函数的方式。
实战案例10-10:Lambda函数的使用
# 基本的lambda函数
add = lambda x, y: x + y
print(f"5 + 3 = {add(5, 3)}") # 8
# 与内置函数结合使用
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 使用lambda过滤偶数
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(f"偶数: {even_numbers}") # [2, 4, 6, 8, 10]
# 使用lambda映射平方数
squared_numbers = list(map(lambda x: x ** 2, numbers))
print(f"平方数: {squared_numbers}") # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
# 使用lambda排序
pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')]
pairs.sort(key=lambda pair: pair[1]) # 按第二个元素排序
print(f"按字母排序: {pairs}") # [(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]
# 在GUI编程中的使用(模拟)
def create_button(text, on_click):
"""模拟创建按钮"""
print(f"创建按钮: '{text}'")
print("模拟点击按钮...")
on_click()
# 使用lambda作为回调函数
create_button("点击我", lambda: print("按钮被点击了!"))
# 多个参数的lambda
multiply = lambda x, y, z: x * y * z
print(f"2 * 3 * 4 = {multiply(2, 3, 4)}") # 24
# 立即执行的lambda函数
result = (lambda x: x ** 2)(5)
print(f"立即执行的结果: {result}") # 25
4.2 闭包(Closure)
闭包是引用了外部函数变量的内部函数。
实战案例10-11:闭包的使用
def outer_function(msg):
"""外部函数"""
message = msg
def inner_function():
"""内部函数(闭包)"""
print(message) # 引用外部函数的变量
return inner_function
# 创建闭包
hello_func = outer_function("Hello")
goodbye_func = outer_function("Goodbye")
# 调用闭包
hello_func() # 输出: Hello
goodbye_func() # 输出: Goodbye
# 更实用的例子:计数器
def counter():
"""创建计数器"""
count = 0
def increment():
nonlocal count # 使用外部变量
count += 1
return count
return increment
# 创建两个独立的计数器
counter1 = counter()
counter2 = counter()
print(f"计数器1: {counter1()}") # 1
print(f"计数器1: {counter1()}") # 2
print(f"计数器2: {counter2()}") # 1
print(f"计数器1: {counter1()}") # 3
print(f"计数器2: {counter2()}") # 2
# 闭包在实际中的应用:配置函数
def configurator(initial_config):
"""创建配置管理器"""
config = initial_config.copy()
def get(key):
return config.get(key)
def set(key, value):
config[key] = value
return config
def update(new_config):
config.update(new_config)
return config
# 返回多个函数
return get, set, update
# 使用配置管理器
get_config, set_config, update_config = configurator({
"debug": False,
"log_level": "INFO"
})
print(f"初始日志级别: {get_config('log_level')}") # INFO
set_config("log_level", "DEBUG")
print(f"更新后的日志级别: {get_config('log_level')}") # DEBUG
update_config({"max_connections": 100, "timeout": 30})
print(f"所有配置: {get_config('_')}") # 需要修改get函数来支持返回所有配置
4.3 装饰器(Decorator)基础
装饰器是一种修改函数行为的特殊函数。
实战案例10-12:装饰器的使用
# 简单的装饰器
def simple_decorator(func):
"""简单的装饰器"""
def wrapper():
print("函数执行前")
result = func()
print("函数执行后")
return result
return wrapper
@simple_decorator
def say_hello():
"""问候函数"""
print("Hello!")
# 使用装饰器
say_hello()
# 输出:
# 函数执行前
# Hello!
# 函数执行后
# 带参数的装饰器
def repeat(n):
"""重复执行函数的装饰器"""
def decorator(func):
def wrapper(*args, **kwargs):
for i in range(n):
print(f"第 {i+1} 次执行:")
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(3)
def greet(name):
"""问候指定的人"""
print(f"Hello, {name}!")
greet("Alice")
# 输出:
# 第 1 次执行:
# Hello, Alice!
# 第 2 次执行:
# Hello, Alice!
# 第 3 次执行:
# Hello, Alice!
# 实用的装饰器:计时器
import time
def timer(func):
"""计算函数执行时间的装饰器"""
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"函数 {func.__name__} 执行时间: {end_time - start_time:.6f} 秒")
return result
return wrapper
@timer
def slow_function():
"""模拟耗时函数"""
time.sleep(1)
return "完成"
result = slow_function() # 输出: 函数 slow_function 执行时间: 1.000000 秒
# 保留原函数的元信息
def preserve_metadata(func):
"""保留函数元信息的装饰器"""
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
wrapper.__name__ = func.__name__
wrapper.__doc__ = func.__doc__
return wrapper
# 使用functools.wraps更简单
from functools import wraps
def better_decorator(func):
"""更好的装饰器(保留元信息)"""
@wraps(func)
def wrapper(*args, **kwargs):
print("装饰器逻辑")
return func(*args, **kwargs)
return wrapper
@better_decorator
def documented_function():
"""这是一个有文档的函数"""
print("函数执行")
print(f"函数名: {documented_function.__name__}") # documented_function
print(f"文档: {documented_function.__doc__}") # 这是一个有文档的函数
五、 综合实战:数据分析管道
现在,让我们创建一个综合性的数据分析管道,应用本章所学的函数知识。
项目目标:
- 使用函数构建数据处理管道
- 应用各种参数传递技巧
- 使用装饰器添加功能(如日志、计时)
- 实现可配置的数据处理流程
- 提供灵活的数据分析功能
代码实现:
# 数据分析管道系统
def data_analysis_pipeline():
"""数据分析管道主函数"""
# 示例数据
data = [
{"name": "Alice", "age": 25, "score": 85, "department": "Engineering"},
{"name": "Bob", "age": 30, "score": 92, "department": "Marketing"},
{"name": "Charlie", "age": 35, "score": 78, "department": "Engineering"},
{"name": "Diana", "age": 28, "score": 95, "department": "Sales"},
{"name": "Eve", "age": 32, "score": 88, "department": "Engineering"},
{"name": "Frank", "age": 40, "score": 76, "department": "Marketing"},
{"name": "Grace", "age": 27, "score": 91, "department": "Sales"},
{"name": "Henry", "age": 45, "score": 83, "department": "Engineering"}
]
# 定义处理函数
def load_data():
"""加载数据"""
print("加载数据...")
return data
@timer
def filter_data(data, **filters):
"""过滤数据"""
print("过滤数据...")
filtered_data = data
for key, value in filters.items():
if key == "min_age":
filtered_data = [item for item in filtered_data if item["age"] >= value]
elif key == "max_age":
filtered_data = [item for item in filtered_data if item["age"] <= value]
elif key == "min_score":
filtered_data = [item for item in filtered_data if item["score"] >= value]
elif key == "department":
filtered_data = [item for item in filtered_data if item["department"] == value]
print(f"过滤后剩余 {len(filtered_data)} 条记录")
return filtered_data
def transform_data(data, *transformations):
"""转换数据"""
print("转换数据...")
transformed_data = data.copy()
for transformation in transformations:
if transformation == "add_grade":
for item in transformed_data:
score = item["score"]
if score >= 90:
item["grade"] = "A"
elif score >= 80:
item["grade"] = "B"
elif score >= 70:
item["grade"] = "C"
else:
item["grade"] = "D"
elif transformation == "add_age_group":
for item in transformed_data:
age = item["age"]
if age < 30:
item["age_group"] = "Young"
elif age < 40:
item["age_group"] = "Middle"
else:
item["age_group"] = "Senior"
return transformed_data
def analyze_data(data, *analyses, **options):
"""分析数据"""
print("分析数据...")
results = {}
for analysis in analyses:
if analysis == "average_score":
total = sum(item["score"] for item in data)
results["average_score"] = total / len(data)
elif analysis == "department_stats":
dept_stats = {}
for item in data:
dept = item["department"]
if dept not in dept_stats:
dept_stats[dept] = {"count": 0, "total_score": 0}
dept_stats[dept]["count"] += 1
dept_stats[dept]["total_score"] += item["score"]
for dept, stats in dept_stats.items():
stats["average_score"] = stats["total_score"] / stats["count"]
results["department_stats"] = dept_stats
elif analysis == "age_score_correlation":
# 简化的相关性计算
ages = [item["age"] for item in data]
scores = [item["score"] for item in data]
# 使用numpy会更好,但这里使用简单实现
mean_age = sum(ages) / len(ages)
mean_score = sum(scores) / len(scores)
numerator = sum((age - mean_age) * (score - mean_score) for age, score in zip(ages, scores))
denominator = (sum((age - mean_age) ** 2 for age in ages) *
sum((score - mean_score) ** 2 for score in scores)) ** 0.5
if denominator != 0:
results["age_score_correlation"] = numerator / denominator
else:
results["age_score_correlation"] = 0
return results
def format_results(results, format_type="text"):
"""格式化结果"""
print("格式化结果...")
if format_type == "text":
output = []
for key, value in results.items():
if key == "average_score":
output.append(f"平均分数: {value:.2f}")
elif key == "department_stats":
output.append("部门统计:")
for dept, stats in value.items():
output.append(f" {dept}: {stats['count']}人, 平均分: {stats['average_score']:.2f}")
elif key == "age_score_correlation":
output.append(f"年龄与分数相关性: {value:.3f}")
return "\n".join(output)
elif format_type == "json":
import json
return json.dumps(results, indent=2)
else:
return str(results)
# 构建处理管道
def process_pipeline(**config):
"""数据处理管道"""
print("=" * 50)
print("开始数据处理管道")
print("=" * 50)
# 加载数据
raw_data = load_data()
# 过滤数据
filtered_data = filter_data(
raw_data,
min_age=config.get("min_age", 0),
max_age=config.get("max_age", 100),
min_score=config.get("min_score", 0),
department=config.get("department", None)
)
# 转换数据
transformed_data = transform_data(
filtered_data,
*config.get("transformations", [])
)
# 分析数据
analysis_results = analyze_data(
transformed_data,
*config.get("analyses", []),
**config.get("analysis_options", {})
)
# 格式化结果
formatted_results = format_results(
analysis_results,
format_type=config.get("format", "text")
)
print("=" * 50)
print("数据处理管道完成")
print("=" * 50)
return formatted_results
# 运行不同配置的管道
print("运行数据分析管道...")
# 配置1:基本分析
config1 = {
"analyses": ["average_score"],
"format": "text"
}
result1 = process_pipeline(**config1)
print("\n配置1结果:")
print(result1)
# 配置2:部门统计
config2 = {
"analyses": ["department_stats"],
"format": "text"
}
result2 = process_pipeline(**config2)
print("\n配置2结果:")
print(result2)
# 配置3:复杂分析
config3 = {
"min_age": 30,
"max_age": 40,
"min_score": 80,
"transformations": ["add_grade", "add_age_group"],
"analyses": ["average_score", "department_stats", "age_score_correlation"],
"format": "text"
}
result3 = process_pipeline(**config3)
print("\n配置3结果:")
print(result3)
# 配置4:JSON格式输出
config4 = {
"department": "Engineering",
"analyses": ["average_score", "department_stats"],
"format": "json"
}
result4 = process_pipeline(**config4)
print("\n配置4结果:")
print(result4)
# 运行数据分析管道
if __name__ == "__main__":
data_analysis_pipeline()
总结与展望
通过本篇文章的深入学习,我们全面掌握了Python中的函数定义与参数传递:
-
函数基础:
- 掌握了函数的基本定义和调用方法
- 学会了使用文档字符串描述函数功能
- 理解了函数作用域和变量访问规则
-
参数传递:
- 掌握了位置参数和默认参数的使用
- 学会了关键字参数和可变参数的使用
- 理解了参数传递的顺序规则和最佳实践
-
高级函数特性:
- 掌握了lambda函数的使用场景
- 学会了闭包的创建和应用
- 理解了装饰器的原理和使用方法
-
综合应用:
- 通过数据分析管道项目,将所学知识融会贯通
- 学会了如何构建灵活的数据处理系统
- 实现了完整的函数化编程解决方案
函数是Python编程的核心概念,掌握好函数定义和参数传递技巧,对于编写高质量、可维护的Python代码至关重要。函数化编程不仅是一种技术,更是一种思维方式,它帮助我们构建更加模块化、可测试和可重用的代码。
思考题:
- 在什么情况下应该使用默认参数?使用默认参数时需要注意什么?
*args和**kwargs有什么区别?它们各自适用于什么场景?- 闭包和普通函数有什么区别?在什么情况下应该使用闭包?
- 装饰器是如何工作的?它们在实际项目中有哪些常见用途?
- 在数据分析管道的基础上,还可以添加哪些数据处理功能来增强其实用性?
更多推荐

所有评论(0)