Python中如何用functools.partial处理可变长度参数?
问题描述
我有一个使用*args的函数及对应的lambda函数:
def draw_figures(picture: Picture, *figures: Figure): # 在图片上绘制图形 ... figures = [figure1, figure2, figure3] draw_fun = lambda new_picture: draw_figures(new_picture, *figures)
这段代码生成的draw_fun可以传入图片,在其上绘制已选定的图形。我尝试用偏函数实现类似功能:
import functools draw_fun = functools.partial(draw_figures, *figures) draw_fun(other_picture)
但这段代码无法正常工作,因为draw_figures会把第一个图形当作picture参数。这符合Python文档中对partial的描述:新函数传入的位置参数会追加到定义partial时提供的参数之后(文档中的partial实现逻辑如下):
# 来自Python文档 def partial(func, /, *args, **keywords): def newfunc(*fargs, **fkeywords): newkeywords = {**keywords, **fkeywords} return func(*args, *fargs, **newkeywords) newfunc.func = func newfunc.args = args newfunc.keywords = keywords return newfunc
请问有没有办法用partial实现我想要的功能?
解决方案
当然可以,核心问题是partial会把预绑定的参数放在调用时传入参数的前面,而我们需要把调用时传入的picture作为draw_figures的第一个参数,预定义的figures作为后续可变参数。可以通过以下几种方式实现:
方法1:包装函数+partial
先定义一个反转参数顺序的包装函数,再用partial绑定预定义的figures:
import functools def _reverse_draw(target_figures, picture): return draw_figures(picture, *target_figures) draw_fun = functools.partial(_reverse_draw, figures)
调用时直接传入图片即可:
draw_fun(other_picture)
这个方法完全通过partial实现,没有使用lambda。
方法2:带默认参数的partial+lambda(简洁版)
如果可以接受少量lambda代码,也可以直接用partial绑定figures作为默认参数:
import functools draw_fun = functools.partial(lambda pic, figs=figures: draw_figures(pic, *figs))
调用方式同样是draw_fun(other_picture),效果和原lambda一致。
方法3:利用关键字参数绑定(需调整调用方式)
如果不想修改原函数,也可以在调用partial生成的函数时,通过关键字参数指定picture:
import functools draw_fun = functools.partial(draw_figures, *figures) draw_fun(picture=other_picture)
这种方法不需要额外包装函数,但调用时必须用关键字参数传入图片。
内容的提问来源于stack exchange,提问作者ledermauss
相关产品推荐
相关产品推荐

