function call - default value & collecting arguments

bruno.desthuilliers at gmail.com bruno.desthuilliers at gmail.com
Wed Apr 2 15:52:47 EDT 2008


On 2 avr, 21:03, "Primoz Skale" <primoz.skale.li... at gmail.com> wrote:
> Hello!
>
> I am fairly new to Python, so I apologise if this is a 'newbie' question.
>
> First define a simple function:
>
> def f(a=0):
>     print a
>
> >> f(1)
> 1
> >>f()
>
> 0
>
> Argument a in function f() is set at default value of 0, if it is not passed
> to the function at the function call. I get this! :)
>
> I also understand (fairly) how to collect arguments. For example, let's
> define another function:
>
> def f(*a):
>    print a

This means that f takes any number of optional positional arguments.
If nothing is passed, within f, 'a' will be an empty tuple. Note that
this is *not* the usual way to define a function taking multiple
(mandatory) arguments.

> >>f(1)
> (1,)
> >>f(1,2)
> (1,2)
> >>f()
>
> ()
>
> OK, everything allright till so fair. But! :) Now define third function as:
>
> def f(*a):
>    print a[0]
>
> In this case, function only prints first argument in the tuple:

*If* there's one.

> >>f(1,2,3)
> 1
> >>f(3)
> 3
> >>f()    #no arguments passed

IndexError ?


> Traceback (most recent call last):
>   File "<pyshell#425>", line 1, in <module>
>     f() #no arguments passed
>   File "<pyshell#422>", line 2, in f
>     print a[0]
> IndexError: tuple index out of range

Bingo.

> Then I tried to define the function as:
>
> def f(*a=(0,)):

SyntaxError ?

>   print a[0]  #this should come next, but we get error msg instead, saying
>
>           SyntaxError: invalid syntax

Bingo.

> but it does not work this way. Now my 'newbie' question: Why not? :)

Condescending answer : "because" !-)
(Sorry, couldn't resist.)

More seriously, I can't tell you why this is not allowed, but :

> I wanted to write function in this way, because then we can call function
> without any arguments, and it would still print 0 (in this case).

def f(*a):
    try:
        print a[0]
    except IndexError:
        print 0

or

def f(*a):
    if not a:
        a = (0,)
    print a[0]

or (slightly more involved, and certainly overkill):

def with_default_args(default):
    def decorator(func):
        def wrapper(*args):
            if not args:
                args = default
            return func(*args)
        return wrapper
    return decorator

@with_default_args((0,))
def f(*a):
    print a[0]

HTH





More information about the Python-list mailing list