Python新手突破瓶颈指南:部分函数 functools.partial 理解和应用

2024-08-06 12:49:48 浏览数 (1)

简介: 本系列文章专为提升编程技能的 Python 新手设计,深入解析 Python 的高级特性和内置工具。笔者通过学习他人项目中未掌握的知识点进行学习总结,一起提编程水平,突破代码能力。

functools.partial 是 Python 的标准库 functools 模块中的一个函数,用于创建部分函数(部分应用)。在中文中,可以将 functools.partial 称为“部分函数应用”或“函数部分应用”。

用法和用途

functools 内方法 partial 用于将一个函数的一部分参数固定,从而创建一个新的函数,这个新函数只需要传递剩余的参数。这样做的好处是,可以简化函数调用,特别是在某些参数经常保持不变的情况下。

代码语言:javascript复制
functools.partial(func, *args, **keywords)
  • func:要部分应用的原函数。
  • *args:要固定的参数。
  • **keywords:要固定的关键字参数

简单示例

假设我们有一个函数 power,用于计算一个数的幂:

代码语言:javascript复制
def power(base, exponent):
    return base ** exponent

如果我们经常需要计算一个数的平方,可以使用 functools.partial 来创建一个新的函数 square,该函数总是计算平方(即 exponent 固定为 2)。

代码语言:javascript复制
import functools

# 创建一个新的函数 square,固定 exponent 参数为 2
square = functools.partial(power, exponent=2)

# 使用 square 计算 3 的平方
print(square(3))  # 输出 9

# 使用 square 计算 5 的平方
print(square(5))  # 输出 25

在这个例子中,square 是一个新的函数,它等价于调用 power(base, 2)。

更多示例

  1. 固定列表的排序方式

假设我们有一个列表,需要反复按降序排序:

代码语言:javascript复制
import functools

# 原始排序函数
def sort_list(lst, reverse=False):
    return sorted(lst, reverse=reverse)

# 创建一个新的函数 sort_desc,固定 reverse 参数为 True
sort_desc = functools.partial(sort_list, reverse=True)

# 使用 sort_desc 对列表进行降序排序
lst = [1, 3, 2, 5, 4]
sorted_lst = sort_desc(lst)
print(sorted_lst)  # 输出 [5, 4, 3, 2, 1]
  1. 固定制化输出格式

假设我们有一个函数 greet,用于输出问候语:

代码语言:javascript复制
def greet(name, greeting="Hello"):
    return f"{greeting}, {name}!"

# 创建一个新的函数 greet_john,固定 name 参数为 "Qi"
greet_john = functools.partial(greet, name="Qi")

# 使用 greet_john 输出不同的问候语
print(greet_john(greeting="Hi"))  # 输出 Hi, Qi!
print(greet_john(greeting="Good morning"))  # 输出 Good morning, Qi!

机制和场景

有的文章中,翻译为“冻结函数”,觉得并不合适。

“冻结”一词通常意味着将一个对象或状态完全固定下来,不再改变。而 functools.partial 创建的函数并没有完全固定原函数的所有参数,只是预设了一部分参数,剩余的参数仍然可以在调用时传递。

这里再解释下 functools.partial 的工作机制

  1. 接受一个函数和部分参数。
  2. 返回一个新的函数,这个新函数可以接受剩余的参数。

例如:

代码语言:javascript复制
import functools

def multiply(x, y):
    return x * y

# 创建一个新的函数 double,把第一个参数 x 固定为 2
double = functools.partial(multiply, 2)

# 现在 double 只需要一个参数 y
print(double(5))  # 输出 10,因为 2 * 5 = 10

在这个例子中,double 并不是“冻结”了 multiply 函数,而是创建了一个新的函数 double,它总是将第一个参数设为 2。调用 double 时,仍然需要提供第二个参数。

使用场景

最后下总结下此函数的一些使用场景:

  1. 简化回调函数 在回调函数中,有时需要传递额外的参数,通过 functools.partial 可以简化回调函数的定义。
  2. 简化代码 当某些函数调用中有固定参数时,可以通过部分应用来简化代码,使代码更具可读性和可维护性。
  3. 创建高阶函数 可以通过部分应用创建更为通用和灵活的高阶函数。

0 人点赞