0

My question is related to this one, however the **kwargs solution there isn't working for me.

Let's say I have some functions as shown below. func_a prints the values of arg1 and arg2. func_b prints the values of arg1 and arg3. So arg1 is common to both functions. I now have a function, func, that calls both func_a and func_b. In the arguments to func I want to be able to pass arg1, with arg2 and arg3 as optional arguments, hence why I set arg2 and arg3 to None by default. However, when I try to call func(arg1='how', arg2='are') I get an unexpected keyword argument error. How can I fix this?

def func_a(arg1, arg2=None):
    print(arg1)
    if arg2 is not None:
        print(arg2)

def func_b(arg1, arg3=None):
    print(arg1)
    if arg3 is not None:
        print(arg3)

def func(arg1, **kwargs):
    func_a(arg1, **kwargs)
    func_b(arg1, **kwargs)

# Try to call func
func(arg1='how', arg2='are')
how
are
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-11-372fbc7b1e90> in <module>
----> 1 func(arg1='how', arg2='are')

<ipython-input-8-5edc2a4c5bfd> in func(arg1, **kwargs)
     11 def func(arg1, **kwargs):
     12     func_a(arg1, **kwargs)
---> 13     func_b(arg1, **kwargs)

TypeError: func_b() got an unexpected keyword argument 'arg2'
7
  • 1
    Just add **kwargs to both func_a and func_b, maybe? Commented Nov 12, 2019 at 19:25
  • Why not just extract the relevant data for each in func? Broadly passing all the data everywhere seems messy. Commented Nov 12, 2019 at 19:25
  • Python functions are strict about there function signatures, although, you are allowed to write a signature which will pretty much accept anything, i.e. def func(*args, **kwargs). The way you've written your functions, though, they will complain if you pass the incorrect arguments, which is a good thing Commented Nov 12, 2019 at 19:27
  • You're not passing arg3 to func() in your example, that's why func2 can't access it. Commented Nov 12, 2019 at 19:27
  • "the **kwargs solution there isn't working for me." needs to be explained further. What did you try? What did not work? Commented Nov 12, 2019 at 19:32

3 Answers 3

3

kwargs is just a dict of function arguments, so you could just use get to get the relevant arguments for each function, which will return None if they aren't found:

def func_a(arg1, arg2=None):
    print(arg1)
    if arg2 is not None:
        print(arg2)

def func_b(arg1, arg3=None):
    print(arg1)
    if arg3 is not None:
        print(arg3)

def func(arg1, **kwargs):
    func_a(arg1, arg2=kwargs.get("arg2"))
    func_b(arg1, arg3=kwargs.get("arg3"))
Sign up to request clarification or add additional context in comments.

Comments

1

You want to drop blindly arg3 in func_a and arg2 in func_b by allowing them with kwargs but then ignoring them it seems.

def func_a(arg1, arg2=None, **kwargs):
    ...

def func_b(arg1, arg3=None, **kwargs):
   ...

Comments

1
def func_a(**kwargs):
    for key,value in kwargs.items():
        if key=='arg1':
            print(value)
        if key=='arg2' and value!=None:
            print(value)

def func_b(**kwargs):
    for key,value in kwargs.items():
        if key=='arg1':
            print(value)
        if key=='arg3' and value!=None:
            print(value)

def func(**kwargs):
    func_a(**kwargs)
    func_b(**kwargs)

# Try to call func
func(arg1='how', arg3='are')

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.