0Pricing
Python Academy · 课时

functools:partial 与 reduce

使用 partial 创建专用函数,并使用 reduce 折叠序列。

functools:partial 与 reduce 是 CoddyKit 上的免费 Python Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Python Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Python Academy 课程共包含 4 节课。

functools 概览

functools 是标准库模块,包含可操作其他函数或返回其他函数的高阶函数。

import functools

# partial, reduce, lru_cache, wraps, cached_property ...
print(dir(functools))

partial()

functools.partial(func, *args, **kw) 会创建一个新的可调用对象,并预先填充部分参数。

import functools

def power(base, exp):
    return base ** exp

square = functools.partial(power, exp=2)
cube   = functools.partial(power, exp=3)

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

将 partial 用于方法

使用 partial 为方法固定参数,使其可以用作回调函数或事件处理程序。

import functools, logging

logger = logging.getLogger("app")
log_error = functools.partial(logger.log, logging.ERROR)

log_error("Something went wrong")

partial 与 lambda 的比较

与 lambda 相比,partial 更适合预先填充参数,因为它支持序列化,具有良好的 repr,并且能够保留文档字符串。

import functools

mul = lambda x, y: x * y

double_lambda = lambda x: mul(x, 2)            # lambda approach
double_partial = functools.partial(mul, y=2)   # partial approach

print(double_partial(5))   # 10

reduce()

functools.reduce(func, iterable, initial) 使用二元函数从左到右折叠可迭代对象。

import functools, operator

total = functools.reduce(operator.add, [1,2,3,4,5])
print(total)   # 15

product = functools.reduce(operator.mul, [1,2,3,4,5], 1)
print(product) # 120

使用 reduce 构建 max()

通过重新实现 max() 来演示 reduce:

import functools

def my_max(seq):
    return functools.reduce(lambda a, b: a if a > b else b, seq)

print(my_max([3, 1, 4, 1, 5, 9]))  # 9

扁平化嵌套列表

将 reduce 与 operator.iconcat 结合使用,可以扁平化一层嵌套。

import functools, operator

nested = [[1,2],[3,4],[5]]
flat = functools.reduce(operator.iconcat, nested, [])
print(flat)  # [1, 2, 3, 4, 5]

使用 partial 构建 URL

partial 的一个实用模式是固定基础 URL,并创建专用的请求辅助函数。

import functools, urllib.request

def fetch(base, path):
    url = base.rstrip("/") + "/" + path.lstrip("/")
    with urllib.request.urlopen(url) as r:
        return r.read()

github = functools.partial(fetch, "https://api.github.com")
# github("/users/octocat")

wraps():保留元数据

编写装饰器时,请使用 @functools.wraps(wrapped),使包装器保留原函数的名称和文档字符串。

import functools

def decorator(func):
    @functools.wraps(func)
    def wrapper(*args, **kw):
        return func(*args, **kw)
    return wrapper

@decorator
def greet(name):
    """Say hello."""
    return f"Hello, {name}"

print(greet.__name__)  # greet
print(greet.__doc__)   # Say hello.

total_ordering

@functools.total_ordering 会在您定义 __eq__ 和 __lt__/__le__/__gt__/__ge__ 中任意一个方法后,补齐缺少的比较方法。

import functools

@functools.total_ordering
class Version:
    def __init__(self, major, minor):
        self.v = (major, minor)
    def __eq__(self, o): return self.v == o.v
    def __lt__(self, o): return self.v < o.v

print(Version(1,2) >= Version(1,1))  # True

singledispatch

@functools.singledispatch 会创建一个函数,根据第一个参数的类型分派到不同的实现。

import functools

@functools.singledispatch
def process(arg):
    raise NotImplementedError(type(arg))

@process.register(int)
def _(n): return n * 2

@process.register(str)
def _(s): return s.upper()

print(process(5))     # 10
print(process("hi"))  # HI

快速检查

functools.partial(pow, 2) 会创建什么?

复习

partial 会预先填充函数参数;reduce 使用二元函数折叠序列;wraps 保留装饰器元数据;total_ordering 补齐比较方法;singledispatch 根据类型进行分派。

常见问题解答

「functools:partial 与 reduce」课时是免费的吗?

是的 — 「functools:partial 与 reduce」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Python Academy 课程的其余内容,请升级到 CoddyKit PRO。 Python Academy 课程共包含 4 节课。

「functools:partial 与 reduce」这节课中我会学到什么?

使用 partial 创建专用函数,并使用 reduce 折叠序列。 你通过在浏览器中直接运行的动手代码来练习 Python Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Python Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Python Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「functools:partial 与 reduce」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Python Academy 课中编写并运行代码吗?

能。每节 Python Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. itertools:无限与有限迭代器
  2. itertools:组合数学
  3. functools:partial 与 reduce
  4. functools:lru_cache 与 cached_property
← 返回 Python Academy