94

I want to pass all the arguments passed to a function(func1) as arguments to another function(func2) inside func1 This can be done with *args, *kwargs in the called func1 and passing them down to func2, but is there another way?

Originally

def func1(*args, **kwargs):
    func2(*args, **kwargs)

but if my func1 signature is

def func1(a=1, b=2, c=3):

how do I send them all to func2, without using

def func1(a=1, b=2, c=3):
    func2(a, b, c)

Is there a way as in javascript callee.arguments?

Anderson Green
  • 30,230
  • 67
  • 195
  • 328
roopesh
  • 1,636
  • 2
  • 13
  • 16

3 Answers3

71

Explicit is better than implicit but if you really don't want to type a few characters:

def func1(a=1, b=2, c=3):
    func2(**locals())

locals() are all local variables, so you can't set any extra vars before calling func2 or they will get passed too.

Jochen Ritzel
  • 104,512
  • 31
  • 200
  • 194
  • 11
    This will have the flaw that if you've created local variables before calling `func2`, then they will also be passed to `func2`. – Ned Batchelder Jun 29 '10 at 00:12
  • 4
    maybe you could copy locals right at the beginning of the function? – Bwmat Jun 29 '10 at 00:45
  • Now I remember reading about `locals`. I was thinking too much about `vars()` and couldn't remember `locals()`. Should have read the documents. I guess vars() can be used too. – roopesh Jun 29 '10 at 01:02
  • 6
    This would not work for class functions as it will get multiple values for self – Bhaskar Jul 08 '14 at 22:08
  • @Bhaskar: Is there any way around that? – orome Apr 16 '16 at 17:35
  • @Bhaskar, can you elaborate on the problem? I'm only seeing one copy of `self`, even when using multiple inheritance. What's the "this" that won't work, using `locals()` at all, or trying to save a copy of the result as a way to have a record after a local variable has been created? – kuzzooroo Sep 08 '16 at 03:30
  • 13
    Ouch, I hate this one. The reason is that `locals()` is the wrong concept - you want to pass "all the parameters" not "all the local variables". All sorts of innocent changes - like adding a local variable before this line, or moving a function to be a method or vice versa - can break this code. More, the reader has to scratch their head to figure it out. – Tom Swirly Feb 26 '17 at 16:12
  • Is there a lean general solution to pass mixed parameters from arguments and keyword arguments? – Nex Apr 11 '19 at 08:34
12

Provided that the arguments to func1 are only keyword arguments, you could do this:

def func1(a=1, b=2, c=3):
    func2(**locals())
Kip Streithorst
  • 425
  • 3
  • 8
6

As others have said, using locals() might cause you to pass on more variables than intended, if func1() creates new variables before calling func2().

This is can be circumvented by calling locals() as the first thing, like so:

def func1(a=1, b=2,c=3):
    par = locals()

    d = par["a"] + par["b"]

    func2(**par)
Olsgaard
  • 1,006
  • 9
  • 19