七、高阶函数
7.1 函数作为参数
# 将函数作为参数传递
def apply_operation(func, x, y):
"""应用给定的函数到两个参数"""
return func(x, y)
def add(a, b):
return a + b
def multiply(a, b):
return a * b
print(apply_operation(add, 10, 20)) # 30
print(apply_operation(multiply, 10, 20)) # 200
print(apply_operation(lambda x, y: x - y, 20, 10)) # 10
# 回调函数
def process_data(data, callback):
"""处理数据并调用回调函数"""
result = [x * 2 for x in data]
callback(result)
def print_result(data):
print(f"处理结果: {data}")
def save_result(data):
print(f"保存结果: {data}")
process_data([1, 2, 3, 4, 5], print_result)
process_data([1, 2, 3, 4, 5], save_result)
# 排序函数作为参数
def sort_by_key(items, key_func):
return sorted(items, key=key_func)
students = [
{"name": "张三", "score": 85},
{"name": "李四", "score": 92},
{"name": "王五", "score": 78}
]
sorted_by_score = sort_by_key(students, lambda s: s["score"])
print(f"按分数排序: {sorted_by_score}")
7.2 函数作为返回值
# 返回函数(闭包)
def make_multiplier(n):
def multiplier(x):
return x * n
return multiplier
times_2 = make_multiplier(2)
times_3 = make_multiplier(3)
print(times_2(10)) # 20
print(times_3(10)) # 30
# 根据条件返回不同函数
def get_operation(op):
if op == "+":
return lambda a, b: a + b
elif op == "-":
return lambda a, b: a - b
elif op == "*":
return lambda a, b: a * b
elif op == "/":
return lambda a, b: a / b if b != 0 else 0
else:
return lambda a, b: None
add_func = get_operation("+")
sub_func = get_operation("-")
print(add_func(10, 20)) # 30
print(sub_func(20, 10)) # 10
# 函数生成器
def create_counter():
count = 0
def counter():
nonlocal count
count += 1
return count
return counter
counter1 = create_counter()
counter2 = create_counter()
print(counter1()) # 1
print(counter1()) # 2
print(counter2()) # 1
7.3 内置高阶函数
# map - 映射
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x ** 2, numbers))
print(f"map平方: {squared}")
# filter - 过滤
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(f"filter偶数: {evens}")
# reduce - 累积
from functools import reduce
sum_all = reduce(lambda a, b: a + b, numbers)
print(f"reduce求和: {sum_all}")
# sorted - 排序
words = ["apple", "banana", "pear", "watermelon"]
sorted_by_len = sorted(words, key=len)
print(f"sorted按长度: {sorted_by_len}")
# zip - 并行遍历
names = ["张三", "李四", "王五"]
scores = [85, 92, 78]
combined = list(zip(names, scores))
print(f"zip合并: {combined}")
# enumerate - 带索引遍历
for i, name in enumerate(names, 1):
print(f"{i}. {name}")
# any/all - 条件判断
has_even = any(x % 2 == 0 for x in numbers)
all_positive = all(x > 0 for x in numbers)
print(f"any有偶数: {has_even}")
print(f"all全正数: {all_positive}")
八、生成器函数
8.1 生成器基础
# 生成器函数:使用yield关键字
def count_up_to(n):
"""生成从0到n-1的数字"""
i = 0
while i < n:
yield i
i += 1
# 使用生成器
for num in count_up_to(5):
print(num, end=" ")
print()
# 生成器对象
gen = count_up_to(3)
print(next(gen)) # 0
print(next(gen)) # 1
print(next(gen)) # 2
# print(next(gen)) # StopIteration
# 斐波那契生成器
def fibonacci_gen():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
fib = fibonacci_gen()
for _ in range(10):
print(next(fib), end=" ")
print()
8.2 生成器表达式
# 生成器表达式(类似列表推导式,但使用圆括号)
squares = (x ** 2 for x in range(10))
print(type(squares)) # <class 'generator'>
for sq in squares:
print(sq, end=" ")
print()
# 生成器表达式是惰性求值
even_squares = (x ** 2 for x in range(20) if x % 2 == 0)
print(f"前5个偶数平方: {list(even_squares)[:5]}")
# 内存效率对比
import sys
list_comprehension = [x ** 2 for x in range(10000)]
generator_expr = (x ** 2 for x in range(10000))
print(f"列表占用: {sys.getsizeof(list_comprehension)} bytes")
print(f"生成器占用: {sys.getsizeof(generator_expr)} bytes")
# 生成器用于管道处理
numbers = range(10)
squared = (x ** 2 for x in numbers)
evens = (x for x in squared if x % 2 == 0)
result = list(evens)
print(f"管道处理结果: {result}")
8.3 生成器方法
# send():向生成器发送值
def echo():
while True:
received = yield
print(f"收到: {received}")
gen = echo()
next(gen) # 启动生成器
gen.send("Hello")
gen.send("World")
# 带返回值的生成器
def accumulator():
total = 0
while True:
value = yield total
if value is None:
break
total += value
return total
acc = accumulator()
next(acc) # 启动
print(acc.send(10)) # 10
print(acc.send(20)) # 30
print(acc.send(30)) # 60
try:
acc.send(None)
except StopIteration as e:
print(f"总和: {e.value}")
# throw():向生成器抛出异常
def generator():
try:
yield 1
yield 2
except ValueError:
yield 3
yield 4
gen = generator()
print(next(gen)) # 1
print(gen.throw(ValueError)) # 3
print(next(gen)) # 4
# close():关闭生成器
def infinite_gen():
i = 0
while True:
yield i
i += 1
gen = infinite_gen()
print(next(gen)) # 0
print(next(gen)) # 1
gen.close()
# print(next(gen)) # StopIteration
8.4 生成器的实际应用
# 1. 大文件逐行读取(节省内存)
def read_large_file(file_path):
"""逐行读取大文件"""
with open(file_path, 'r') as f:
for line in f:
yield line.strip()
# 2. 无限序列生成
def primes():
"""生成无限素数序列"""
yield 2
n = 3
while True:
is_prime = True
for i in range(3, int(n ** 0.5) + 1, 2):
if n % i == 0:
is_prime = False
break
if is_prime:
yield n
n += 2
# 3. 分页数据
def paginate(data, page_size):
"""分页生成器"""
for i in range(0, len(data), page_size):
yield data[i:i + page_size]
# 4. 数据流处理管道
def read_lines():
yield "apple 10"
yield "banana 20"
yield "cherry 30"
def parse_lines(lines):
for line in lines:
name, count = line.split()
yield name, int(count)
def filter_high(items, threshold):
for name, count in items:
if count > threshold:
yield name
# 使用示例
print("前10个素数:")
prime_gen = primes()
for _ in range(10):
print(next(prime_gen), end=" ")
print()
data = list(range(1, 21))
for page in paginate(data, 5):
print(f"页: {page}")
# 数据流处理
lines = read_lines()
parsed = parse_lines(lines)
filtered = filter_high(parsed, 15)
print(f"计数大于15的: {list(filtered)}")
九、函数式编程工具
9.1 functools模块
from functools import partial, reduce, wraps, lru_cache, singledispatch
# partial:固定部分参数
def power(base, exponent):
return base ** exponent
square = partial(power, exponent=2)
cube = partial(power, exponent=3)
print(square(5)) # 25
print(cube(5)) # 125
# reduce:累积计算
numbers = [1, 2, 3, 4, 5]
product = reduce(lambda x, y: x * y, numbers)
print(f"乘积: {product}")
# lru_cache:缓存装饰器
@lru_cache(maxsize=128)
def fib(n):
if n <= 1:
return n
return fib(n - 1) + fib(n - 2)
print(f"fib(50) = {fib(50)}")
print(fib.cache_info())
# singledispatch:单分派泛函数
@singledispatch
def process(value):
print(f"默认处理: {value}")
@process.register(int)
def _(value):
print(f"处理整数: {value}")
@process.register(str)
def _(value):
print(f"处理字符串: {value}")
@process.register(list)
def _(value):
print(f"处理列表,长度: {len(value)}")
process(100)
process("hello")
process([1, 2, 3])
process(3.14) # 使用默认处理
9.2 itertools模块
import itertools
# count:无限计数器
counter = itertools.count(start=10, step=2)
for _ in range(5):
print(next(counter), end=" ")
print()
# cycle:无限循环
colors = itertools.cycle(["红", "黄", "蓝"])
for _ in range(7):
print(next(colors), end=" ")
print()
# repeat:重复值
repeated = itertools.repeat("Python", 3)
print(list(repeated))
# chain:连接多个迭代器
list1 = [1, 2, 3]
list2 = [4, 5, 6]
chained = itertools.chain(list1, list2)
print(list(chained))
# zip_longest:不等长压缩
names = ["张三", "李四", "王五"]
scores = [85, 92]
combined = itertools.zip_longest(names, scores, fillvalue="无成绩")
print(list(combined))
# permutations:排列
perms = list(itertools.permutations([1, 2, 3], 2))
print(f"排列: {perms}")
# combinations:组合
combs = list(itertools.combinations([1, 2, 3, 4], 2))
print(f"组合: {combs}")
# product:笛卡尔积
products = list(itertools.product([1, 2], ['a', 'b']))
print(f"笛卡尔积: {products}")
# groupby:分组
data = [("苹果", 10), ("苹果", 20), ("香蕉", 15), ("香蕉", 25)]
data.sort(key=lambda x: x[0])
for key, group in itertools.groupby(data, key=lambda x: x[0]):
values = [item[1] for item in group]
print(f"{key}: {values}")
十、函数最佳实践
10.1 函数设计原则
# 1. 单一职责:一个函数只做一件事
# 不好
def process_user_data(user_data):
validate_user(user_data)
save_user(user_data)
send_notification(user_data)
# 好
def validate_user(user_data): pass
def save_user(user_data): pass
def send_notification(user_data): pass
# 2. 函数命名规范
# 动词开头,小写下划线分隔
def calculate_total(): pass
def is_valid_email(): pass
def get_user_info(): pass
# 3. 参数数量控制
# 避免参数过多(建议不超过3-4个)
# 不好
def create_user(name, age, email, phone, address, city, country): pass
# 好:使用对象或字典
def create_user(user_info): pass
# 4. 避免副作用
# 不好
global_counter = 0
def increment():
global global_counter
global_counter += 1
# 好
def increment(counter):
return counter + 1
# 5. 返回一致的类型
# 不好
def find_user(user_id):
if user_id == 1:
return {"name": "张三"}
return None # 有时返回字典,有时返回None
# 好
def find_user(user_id):
if user_id == 1:
return {"name": "张三"}
return {} # 始终返回字典
10.2 文档字符串(Docstring)
def complex_function(param1, param2, param3=None):
"""
函数的详细说明。
这里可以写更详细的描述,包括函数的功能、
算法说明、注意事项等。
Args:
param1 (int): 第一个参数说明
param2 (str): 第二个参数说明
param3 (list, optional): 第三个参数,默认为None
Returns:
bool: 返回值说明
Raises:
ValueError: 当param1为负数时抛出
Examples:
>>> complex_function(10, "test")
True
>>> complex_function(-1, "test")
Traceback (most recent call last):
...
ValueError
"""
if param1 < 0:
raise ValueError("param1不能为负数")
return True
# 查看文档
print(complex_function.__doc__)
help(complex_function)
10.3 类型提示最佳实践
from typing import List, Dict, Optional, Union, Callable, Any
# 类型别名
UserId = int
UserInfo = Dict[str, Any]
# 复杂类型提示
def process_users(
user_ids: List[UserId],
callback: Optional[Callable[[UserInfo], None]] = None
) -> List[UserInfo]:
"""
处理用户数据
Args:
user_ids: 用户ID列表
callback: 可选的回调函数
Returns:
用户信息列表
"""
results = []
for uid in user_ids:
user_info = {"id": uid, "name": f"User_{uid}"}
if callback:
callback(user_info)
results.append(user_info)
return results
# 使用TypedDict(Python 3.8+)
from typing import TypedDict
class User(TypedDict):
id: int
name: str
age: int
def get_user_info() -> User:
return {"id": 1, "name": "张三", "age": 25}
Python函数是Python编程的核心,从基础的函数定义到高级的装饰器、生成器、函数式编程,Python的函数体系为开发者提供了丰富而强大的编程能力。本文系统性地梳理了Python函数的核心知识点,从基础语法到高级特性,从参数传递到函数式编程,帮助开发者建立完整的知识体系。
来源:
https://xcfsr.cn/