RE: Passing parameters to functions

Discussion in 'Python' started by Robert Brewer, May 24, 2004.

  1. Thomas Philips wrote:
    > The following program passes parameters (inluding another function)
    > into a function.
    >
    > def f(myfunc,m=3,*numbers):
    > sumSquares=myfunc(*numbers[:m])
    > print sumSquares
    >
    > 1. When I run it, Python gives me the following error message:
    > Syntax error. There's an error in your program: *** non-keyword arg
    > after keyword arg


    The "keyword arg" in your function signature is the arg "m=3". Any args
    appearing after it must also be given default values, which *numbers
    doesn't do. My recommendation--just drop the default of 3 unless it's
    critical.

    def f(myfunc, m, *numbers)

    > 2. f passes *arguments[:m] into sumofsquares. It appears to be passing
    > a pointer. But Python doesn't have pointers


    It doesn't have exposed pointers, but it does have references.
    "arguments[:m]" creates a new list object; prepending "*" does a couple
    of things:

    1) It passes each item in that new list as an argument to your supplied
    function, and
    2) Within the sumofsquares scope, it rebinds that list to the name
    "args".

    You might want to reread http://effbot.org/zone/python-objects.htm:
    "Assignment modify namespaces, not objects." In this context, calling
    sumofsquares involves an 'assignment'; within the scope/namespace of the
    function, the name "args" is bound to the objects being passed in (your
    list).

    Hope that helps!


    Robert Brewer
    MIS
    Amor Ministries
    Robert Brewer, May 24, 2004
    #1
    1. Advertising

  2. Thanks for the explanation. A follow up question: Suppose I want to
    pass AT LEAST 2 positional arguments and AT LEAST 2 keyword arguments
    into a function, Then I think I would logically define the function as
    follows

    def f(parg1, parg2, karg1="yes", karg2="no", *pargs, **kargs):
    print parg1, parg2, pargs, karg1, karg2, kargs

    and I expect that
    f(1, 2, 3, 4, 5, karg1="maybe", karg2="maybe not", m="yes", n="no")

    will return
    1 2 (3, 4, 5) "maybe" "maybe not" {'m': "yes", 'n': "no"}

    But instead I get an error:
    f() got multiple values for keyword argument 'karg1'

    For the reasons you outlined earlier, the alternate form
    f(1, 2,karg1="maybe", karg2="maybe not", 3, 4, 5, m="yes", n="no")
    generates a syntax error.

    How can I pass all these arguments into the function cleanly?

    Thomas Philips
    Thomas Philips, May 26, 2004
    #2
    1. Advertising

  3. Robert Brewer

    Jeff Epler Guest

    If you want to have a varying number of positional arguments, and
    require certain keyword arguments, I think you'll be forced to write it
    in a clumsy way, similar to (untested):
    def extract_args(funcname, mapping, *names):
    for i in names:
    try:
    yield mapping
    del mapping
    except KeyError:
    raise TypeError, (
    "%s requires a keyword argument %s" %
    (funcname, repr(i))))

    def f(parg1, parg2, *pargs, **kargs):
    karg1, karg2 = extract_args("f()", kargs, "karg1", "karg2")
    print parg1, parg2, pargs, karg1, karg2, kargs

    When you write code like
    def f(a, b=1)
    Python will accept any of these calls to f:
    f(0)
    f(1, 2)
    f(3, b=4)
    f(a=5, b=6)
    and even
    f(b=7, a=8)
    ... the call that is relevant to your case is the second one. The
    value in b can come from a positional argument or a keyword argument.
    In your case, when you cakk 'f(1, 2, 3, karg=3)' karg gets two
    values---one from the third positional argument, and one from the
    keyword argument.

    Jeff
    Jeff Epler, May 26, 2004
    #3
  4. Thomas Philips wrote:
    > Thanks for the explanation. A follow up question: Suppose I want to
    > pass AT LEAST 2 positional arguments and AT LEAST 2 keyword arguments
    > into a function, Then I think I would logically define the function as
    > follows
    >
    > def f(parg1, parg2, karg1="yes", karg2="no", *pargs, **kargs):
    > print parg1, parg2, pargs, karg1, karg2, kargs
    >
    > and I expect that
    > f(1, 2, 3, 4, 5, karg1="maybe", karg2="maybe not", m="yes", n="no")
    >
    > will return
    > 1 2 (3, 4, 5) "maybe" "maybe not" {'m': "yes", 'n': "no"}
    >
    > But instead I get an error:
    > f() got multiple values for keyword argument 'karg1'
    >
    > [...]
    >
    > How can I pass all these arguments into the function cleanly?


    Maybe this way:

    f (1, 2, karg1="maybe", karg2="maybe not", m="yes", n="no", *[3, 4, 5])

    Greeting,

    Holger
    =?ISO-8859-1?Q?Holger_T=FCrk?=, May 26, 2004
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Thomas Philips

    Passing parameters to functions

    Thomas Philips, May 24, 2004, in forum: Python
    Replies:
    1
    Views:
    336
    Tor Iver Wilhelmsen
    May 24, 2004
  2. teju
    Replies:
    9
    Views:
    652
    Chris Thomasson
    Jan 9, 2008
  3. Ramon F Herrera
    Replies:
    8
    Views:
    475
    Pascal J. Bourguignon
    Sep 13, 2009
  4. JBB123
    Replies:
    1
    Views:
    487
    JBB123
    Dec 8, 2011
  5. Frank Meyer

    Passing two functions as parameters

    Frank Meyer, Aug 16, 2007, in forum: Ruby
    Replies:
    8
    Views:
    128
    Frank Meyer
    Aug 17, 2007
Loading...

Share This Page