CopOnTheRun
CopOnTheRun

Reputation: 1207

Creating a partial function, but preserving the kind of parameters in the resulting function

It's possible to create a partial function in python with the partial function from functools, however doing so will usually change some parameters to be keyword-only parameters. For example:

def foo(a, b, c, d):
    return a*b - c*d

bar = functools.partial(foo, b=2, c=3)

inspect.signature(foo)
# <Signature (a, b, c, d)>

inspect.signature(bar)
# <Signature (a, *, b=2, c=3, d)>

In the example, parameter a keeps its original kind, but d is keyword-only now. Is there a way to bind a function's parameters to some values while preserving the other parameters' kind? In other words, a way to make bar from above functionally equivalent to:

def bar(a, d):
    return a*2 - 3*d

but bar could be any function, and any combination of parameters could be bound.

Upvotes: 4

Views: 654

Answers (1)

a_guest
a_guest

Reputation: 36309

This is not possible with functools.partial. A similar idea was brought up multiple times on the Python-ideas mailing list, see e.g. here or here (also this SO question). The idea was to skip over some of the positional arguments, so in your case you could do:

bar = partial(foo, SKIP, 2, 3)

However that got never implemented, so you can't use it today.

What you can do instead is to wrap your function call inside another function which has the desired signature (either lambda or "normal" function):

def bar(a, d):
    return foo(a, 2, 3, d)

Another option is to require the users of your function to pass arguments via keyword. Without a real use case however it's difficult to judge what would be the best approach.

Upvotes: 2

Related Questions