Checking default arguments

George Sakkis george.sakkis at gmail.com
Sat Feb 3 12:56:28 EST 2007


On Feb 2, 1:30 pm, i... at ifi.uio.no (Igor V. Rafienko) wrote:
> Hi,
>
> I was wondering whether it was possible to find out which parameter
> value is being used: the default argument or the user-supplied one.
> That is:
>
> def foo(x, y="bar"):
>     # how to figure out whether the value of y is
>     # the default argument, or user-supplied?
>
> foo(1, "bar") => user-supplied
> foo(1)        => default
>
> {}.pop seems to be able to make this dictinction.
>
> I've checked the inspect module, but nothing obvious jumped at me. Any
> hints?

I don't know why you might want to distinguish between the two in
practice (the unique object idea mentioned in other posts should
handle most uses cases), but if you insist, here's one way to do it:

import inspect

def determine_supplied_args(func):
    varnames,_,_,defaults = inspect.getargspec(func)
    num_varnames = len(varnames); num_defaults = len(defaults)
    def wrapper(*args, **kwds):
        max_defaults = min(num_defaults, num_varnames-len(args))
        supplied_args = dict(zip(varnames,args))
        default_args = {}
        if max_defaults > 0:
            for var,default in zip(varnames[-max_defaults:], defaults[-
max_defaults:]):
                # if passed as keyword argument, don't use the default
                if var in kwds:
                    supplied_args[var] = kwds[var]
                else:
                    default_args[var] = default
        wrapper._supplied_args = supplied_args
        wrapper._default_args = default_args
        return func(*args, **kwds)
    return wrapper


@determine_supplied_args
def f(x, y='bar', z=None, *args, **kwds):
    print "Supplied:", f._supplied_args
    print "Default:", f._default_args


>>> f(1)
Supplied: {'x': 1}
Default: {'y': 'bar', 'z': None}
>>> f(1, 'bar')
Supplied: {'y': 'bar', 'x': 1}
Default: {'z': None}
>>> f(1, y='bar')
Supplied: {'y': 'bar', 'x': 1}
Default: {'z': None}
>>> f(1, z=None)
Supplied: {'x': 1, 'z': None}
Default: {'y': 'bar'}
>>> f(1, 'bar', None)
Supplied: {'y': 'bar', 'x': 1, 'z': None}
Default: {}
>>> f(1, 'bar', z=None)
Supplied: {'y': 'bar', 'x': 1, 'z': None}
Default: {}
>>> f(1, z=None, y='bar')
Supplied: {'y': 'bar', 'x': 1, 'z': None}
Default: {}


Regards,
George




More information about the Python-list mailing list