如何在支持所有传入参数的同时替换Python函数

时间:2009-08-18 17:39:41

标签: python decorator kwargs

我正在寻找一种装饰任意python函数的方法,以便调用替代函数而不是原始函数,所有参数都作为列表或字典传递。

更确切地说,这样的事情(其中f是任何函数,replacement_f采用列表和字典):

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

但是,我无法在replacement_f内引用new_f。而且我不能使用将replacement_f传递给new_f作为其他参数的默认值的标准技巧,因为我正在使用*args**kwargs变量参数列表

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

我担心这不是很清楚,但如果需要,我很乐意澄清。

由于

4 个答案:

答案 0 :(得分: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

答案 1 :(得分: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):
    ....

答案 2 :(得分:0)

如果我理解正确,你想要将所有参数从一个函数传递给另一个函数。

简单地说:

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

答案 3 :(得分:0)

这是做你的意思吗?未经测试

def replace_func(f, replacement_f):
    nonlocal replacement_f  #<<<<<<<<<<<<<<<py3k magic
    def new_f(*args, **kwargs):
        replacement_f(*args, **kwargs) # args & kwargs will be expanded
    replacement_f = new_f

Python nonlocal statement

编辑:它是一个开始,我确切地混淆了你想要的东西,但我认为非本地会帮助