Home > Net >  A partial wrapper of a python function
A partial wrapper of a python function

Time:04-14

Given the following code,

def myfunc(a=None, b=None, c=None, **kw):
    func(arga=a, argb=b, **kw)
    #do something with c

def func(arga=None, argb=None, argc=None):
    ....

Can I replicate part of the signature of func, namely the missing args, without imitating every missing arg of func manually?

Put it more simply, I want to see argc in keywords of myfunc such that myfunc? would be different. It would contain argc. myfunc(a=None,b=None,c=None,argc=None)

@functools.wraps allows for wrapping a complete functions. Using partial can subtract args. But don't know to add.

CodePudding user response:

yes, it is possible, though not trivial - Python's introspection capabilities allow you to check all parameters the target function declares, and it is possible to build a new function programmatically that will include those attributes automatically.

I have written this for a project of mine, and had exposed the relevant code as my answer here: Signature-changing decorator: properly documenting additional argument

I will not mark this as duplicate, since the other question is more worried about documenting the new function.

If you want to give a try, with your code, maybe with something simpler, you can check the inspect.signature call from the standard library, which allows one to discover everything about parameters and default arguments of the target function.

Building a new function from this information is a bit more tricky, but possible - but one can always resort to a exec call which will can create a new function from a string template. The answer there follows this line.

CodePudding user response:

I'm not sure what is being asked here either but I have here alternative code to functools.partial that might be adapted ???

def mkcall(fs, globals=None,locals=None):
    class func:
        def __init__(f,fcnm=None,params=None,globals=None,locals=None):
            f.nm = fcnm
            f.pm = params
            f.globals = globals
            f.locals = locals

        def __call__(f):
            s = f.nm   f.pm
            eval(s,f.globals,f.locals)    

    if '(' in fs:
        funcn,lbr,r = fs.partition('(')
        tp = lbr   r
        newf = func(funcn,tp,globals,locals)
        callf = newf.__call__
    else:
        callf = eval(fs,globals,locals)
    return callf

#call examples
# mkcall("func(arg)")
# mkcall("func")
  • Related