如何在支持所有传入参数的情况下替换Python函数

0 投票
4 回答
1806 浏览
提问于 2025-04-15 13:41

我想找一种方法,可以装饰一个任意的 Python 函数,让它在被调用时,调用一个替代的函数,而不是原来的那个函数,并且把所有参数作为列表或字典传递。

更具体来说,像这样(其中 f 是任何函数,replacement_f 接受一个列表和一个字典):

def replace_func(f, replacement_f):
    def new_f(*args, **kwargs):
        replacement_f(args, kwargs)
    return new_f

但是,我无法在 new_f 函数内部引用 replacement_f。而且我不能用常规的方法把 replacement_f 作为默认参数传给 new_f,因为我使用了 *args**kwargs 这种可变参数列表。

原始函数被调用的位置不能改变,并且会接受位置参数和命名参数。

我担心这样说不太清楚,但如果需要的话,我很乐意进一步解释。

谢谢

4 个回答

0

如果我理解得没错,你是想把一个函数的所有参数传递给另一个函数。

你只需要这样做:

def replace_func(f, replacement_f):
    def new_f(*args, **kwargs):
        replacement_f(*args, **kwargs) # args & kwargs will be expanded
    return new_f
1

虽然我觉得SilentGhost的回答是最好的解决方案,如果对你有效的话,但为了完整性,这里是你想做的事情的正确版本:

要定义一个可以接受参数的装饰器,你需要增加一个额外的层级:

def replace_function(repl):
    def deco(f):
        def inner_f(*args, **kwargs):
            repl(*args, **kwargs)

        return inner_f
    return deco

现在你可以使用带参数的装饰器了:

@replace_function(replacement_f)
def original_function(*args, **kwargs):
    ....
4

你为什么不试试这个呢:

f = replacement_f

举个例子

>>> def rep(*args):
    print(*args, sep=' -- ')

>>> def ori(*args):
    print(args)

>>> ori('dfef', 32)
('dfef', 32)
>>> ori = rep
>>> ori('dfef', 32)
dfef -- 32

撰写回答