0

Let's assume, I have a function

def func(u,v,w,x, alpha = 4, beta = 5):
    print('u ',u)
    print('v ',v)
    print('x ',w)
    print('u ',x)
    print('** kwarqs: alpha ',alpha)
    print('** kwarqs: beta ',beta)
    return u*4 + v*3 + w*2 + x

I now want to make it a partial-function by using functools.partial. I set the u,v,w variable to a constant and create a function $$part=f(x)|_{u,v,w = \text{const}}$$

u = 2
v = 4
w = 5

part = partial(func,u,v,w, alpha = 'Hello 1', beta = 'Hello 2')
print(part(4))

The result is

u  2
v  4
w  5
x  4   # This is the remaining free variable
** kwarqs: alpha  Hello 1
** kwarqs: beta  Hello 2
34

How can I create functions

f(u) #or f(v),f(w)
f(v,x) #or all other variable combinations
f(v,alpha) # a combination of args and kwargs

?

Best regards


Work arounds are also welcome.

5
  • 1
    basically u wanna overload functions? Commented Mar 29, 2020 at 14:34
  • 1
    Does this help: stackoverflow.com/questions/11173660/… Commented Mar 29, 2020 at 14:34
  • @schwobaseggl - Thank you, I wonder wether something has changed in the last 8 years Commented Mar 29, 2020 at 14:38
  • @albusSimba The third wanted function seems to be overloading. Are partial functions also considered to be overloaded functions? Commented Mar 29, 2020 at 14:42
  • 1
    Nope, it hasn't. Whatever arguments your partial function takes must be kwargs or the last postional arguments of the function passed to partial. Commented Mar 29, 2020 at 14:42

2 Answers 2

3

Can I recommend the use of lambda for your case.

f1 = lambda u : func(u,v,w,x, alpha = 4, beta = 5) 
f2 = lambda v, x: func(u,v,w,x, alpha = 4, beta = 5) 
f3 = lambda v, alpha: func(u,v,w,x, alpha = alpha, beta = 5)  

The usage is the same as what you wanted:

f1(u) #or f(v),f(w)
f2(v,x) #or all other variable combinations
f3(v,alpha) # a combination of args and kwargs
Sign up to request clarification or add additional context in comments.

4 Comments

I got no idea but is this what u wanted?
How is this a useful abstraction when you have to write a specific lambda function (or convential function) with reordered arguments for each individual case?
you can always fix the values before hand similar to partial
Yes, partial has its charme, but if it is not possible to use it in those cases, I would regard this the smoothest solution.
1

Interesting problem. You could go and turn your function into a kwarg-only function:

from functools import wraps, partial

def kwarged(func):
    @wraps(func)
    def wrapper(**kwargs):
        return func(**kwargs)
    return wrapper

Which you can then use to build any partial version:

>>> func = kwarged(func)

>>> f_u = partial(func, v=5, w=2, x=4)
>>> f_u(u=7)
u  7
v  5
w  2
x  4
** kwarqs: alpha  4
** kwarqs: beta  5
51

>>> f_vx = partial(func, u=5, w=2) 
>>> f_vx(v=3, x=6)
u  5
v  3
w  2
x  6
** kwarqs: alpha  4
** kwarqs: beta  5
39
>>> f_vx(v=3, x=6, alpha=9)
u  5
v  3
w  2
x  6
** kwarqs: alpha  9
** kwarqs: beta  5
39

And even though all arguments are kwargs with defaults, you will still have to pass all original positional args not set in partial:

>>> f_vx(v=3, alpha=9)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 10, in wrapper
TypeError: func() missing 1 required positional argument: 'x'

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.