Tailwind CSSTailwind CSS
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
  • 第5章:函数式编程的实践

第5章:函数式编程的实践

5.1 在 Python 中应用函数式编程

Python 是一种多范式语言,虽然以命令式和面向对象编程为主,但它提供了许多支持函数式编程(FP)的特性,如 lambda 函数、高阶函数和不可变数据结构。通过合理利用这些工具,开发者可以在 Python 中实践 FP 的核心原则(如纯函数、不可变性和声明式风格)。本节将介绍如何在 Python 中应用函数式编程,并通过示例展示其实用性。

Python 的函数式特性

Python 内置了一些支持 FP 的工具,尽管它并非纯函数式语言:

  • lambda 函数:用于定义匿名函数,适合简单的函数式操作。
  • 高阶函数:如 map、filter 和 reduce(需从 functools 导入)。
  • 列表推导式与生成器:提供声明式数据处理和惰性求值。
  • 不可变数据类型:如 tuple 和 frozenset。
  • 模块支持:functools(partial、reduce)和 itertools(惰性迭代)。

这些特性为在 Python 中实现 FP 提供了基础。

实现纯函数

纯函数是 FP 的核心,要求无副作用且输出仅依赖输入。在 Python 中,可以通过避免全局变量和 I/O 操作来实现:

# 纯函数
def add(a, b):
    return a + b

# 非纯函数(依赖全局状态)
counter = 0
def increment():
    global counter
    counter += 1
    return counter

# 纯函数版本(使用参数)
def increment_pure(n):
    return n + 1

实践时,尽量将状态作为参数传递,而不是依赖外部变量。

使用高阶函数和 lambda

Python 的 map、filter 和 reduce 是典型的函数式工具,常与 lambda 结合使用:

  • 映射(map):

    numbers = [1, 2, 3, 4]
    squared = list(map(lambda x: x * x, numbers))  # 输出: [1, 4, 9, 16]
    
  • 过滤(filter):

    evens = list(filter(lambda x: x % 2 == 0, numbers))  # 输出: [2, 4]
    
  • 归约(reduce):

    from functools import reduce
    total = reduce(lambda x, y: x + y, numbers)  # 输出: 10
    

这些函数替代了显式循环,使代码更简洁。

不可变性与数据处理

Python 的默认数据结构(如 list 和 dict)是可变的,但可以通过 tuple 和 frozenset 或手动避免修改来实现不可变性:

# 使用 tuple 保持不可变
numbers = (1, 2, 3)
new_numbers = (0,) + numbers  # 输出: (0, 1, 2, 3)
print(numbers)  # 输出: (1, 2, 3) 未变

# 列表推导式生成新数据
lst = [1, 2, 3]
doubled = [x * 2 for x in lst]  # 输出: [2, 4, 6]

避免直接修改(如 lst[0] = 10),保持函数式风格。

惰性求值与生成器

Python 通过生成器支持惰性求值,适用于大数据或无限序列:

def infinite_numbers():
    n = 1
    while True:
        yield n
        n += 1

from itertools import islice
first_few = list(islice(infinite_numbers(), 5))  # 输出: [1, 2, 3, 4, 5]

生成器与 map、filter 结合,进一步增强惰性处理能力:

squares = map(lambda x: x * x, infinite_numbers())
print(list(islice(squares, 3)))  # 输出: [1, 4, 9]

函数组合与 functools

functools 提供了工具来增强函数式特性:

  • partial:部分应用函数。

    from functools import partial
    add_five = partial(add, 5)
    print(add_five(3))  # 输出: 8
    
  • reduce:聚合数据。

  • compose(需借助第三方库如 toolz):

    from toolz import compose
    double = lambda x: x * 2
    add_one = lambda x: x + 1
    transform = compose(double, add_one)
    print(transform(3))  # 输出: 8
    

实践案例:数据转换管道

假设要从列表中筛选正数、平方并求和:

numbers = [-2, -1, 0, 1, 2]
result = reduce(
    lambda x, y: x + y,
    map(lambda x: x * x,
        filter(lambda x: x > 0, numbers))
)
print(result)  # 输出: 5 (1² + 2²)

这种管道式处理体现了声明式编程的优势。

Python 中 FP 的局限与应对

  • 局限:

    • 默认严格求值,需用生成器模拟惰性。
    • 无原生尾递归优化,大递归可能栈溢出。
    • 缺乏模式匹配(3.10 前)。
  • 应对:

    • 用循环替代深递归,或借助 sys.setrecursionlimit。
    • 使用 match(Python 3.10+)模拟模式匹配:
      def factorial(n):
          match n:
              case 0 | 1:
                  return 1
              case _:
                  return n * factorial(n - 1)
      
  • 第三方库:如 toolz、fn.py 提供更多 FP 功能。

小结

在 Python 中应用函数式编程,可以通过 lambda、高阶函数、不可变数据和生成器实现纯函数、不可变性和声明式风格。尽管 Python 不是纯 FP 语言,但其灵活性使其成为实践 FP 的良好平台。通过本节的学习,你可以在日常开发中逐步融入函数式思想。下一节,我们将探讨其他主流语言的函数式特性,拓宽实践视野。

Last Updated:: 2/25/25, 10:59 AM