0

Given a Python function definition of the form:

def foo(a=None, b=1, c='bar'):

How can I dynamically determine which parameters have been set to a value different than their default value? For instance:

foo(48)

I want to be able to dynamically identify that a was the only parameter that was set. The solution I'm seeking would continue to work even if I added additional parameters to the signature (i.e. I don't want to do a manual check if a == None, etc.).

==UPDATE==

To clarify my goal: For some users of function foo, I allow it to be executed regardless. If I identify that user is of user type/class/category Bar then I only want to allow it to succeed only if they called foo with an argument for parameter a. If they provided arguments (or at least, arguments not equal to the defaults) for any other parameter then an Exception should be raised. (I know which user is calling the function based on other global data).

Again, I could simply say if b != 1 or c != 'bar', but then I would have to update it every time foo's signature gets modified.

ChaimKut
  • 2,759
  • 3
  • 38
  • 64

1 Answers1

3

I think your best course of action is to use inspect.

import inspect

def foo(non_default_var, a=None, b=1, c='bar'):
    inspector = inspect.getargspec(foo)
    local_vars = inspector.args                      # = ['d', 'a', 'b', 'c']
    default_values = inspector.defaults              # = (None, 1, 'bar')
    default_vars = local_vars[-len(default_values):] # Since default values are at the end
    for var, default_value in zip(default_vars, list(default_values)): # Now iterate and compare
        print locals()[var] == default_value         # True if the variable is default

I guess this would work even better as a decorator.

The only drawback is that you cannot know if the user intended to use the default value, or entered this value explicitely in the function call.

Flavian Hautbois
  • 2,940
  • 6
  • 28
  • 45