8

How can I programmatically access the default argument values of a method in Python? For example, in the following

def test(arg1='Foo'):
    pass

how can I access the string 'Foo' inside test?

Randomblue
  • 112,777
  • 145
  • 353
  • 547

4 Answers4

17

They are stored in test.func_defaults (python 2) and in test.__defaults__ (python 3).

As @Friedrich reminds me, Python 3 has "keyword only" arguments, and for those the defaults are stored in function.__kwdefaults__

Ricardo Cárdenes
  • 9,004
  • 1
  • 21
  • 34
5

Consider:

def test(arg1='Foo'):
    pass

In [48]: test.func_defaults
Out[48]: ('Foo',)

.func_defaults gives you the default values, as a sequence, in order that the arguments appear in your code.

Apparently, func_defaults may have been removed in python 3.

Marcin
  • 48,559
  • 18
  • 128
  • 201
2

Ricardo Cárdenes is on the right track. Actually getting to the function test inside test is going to be a lot more tricky. The inspect module will get you further, but it is going to be ugly: Python code to get current function into a variable?

As it turns out, you can refer to test inside the function:

def test(arg1='foo'):
    print test.__defaults__[0]

Will print out foo. But refering to test will only work, as long as test is actually defined:

>>> test()
foo
>>> other = test
>>> other()
foo
>>> del test
>>> other()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in test
NameError: global name 'test' is not defined

So, if you intend on passing this function around, you might really have to go the inspect route :(

Community
  • 1
  • 1
Daren Thomas
  • 67,947
  • 40
  • 154
  • 200
  • I was under that impression as well, turns out that `test` is in `test`'s local scope as pointed out in Ricardo's comment on my answer. – Rob Wouters Jan 10 '12 at 16:29
  • 1
    If we do `def test2(): print locals(), '\n\n', globals()`, we see that `test2` is in globals, and there is nothing in locals. – Evgeni Sergeev Aug 10 '16 at 04:28
0

This isn't very elegant (at all), but it does what you want:

def test(arg1='Foo'):
    print(test.__defaults__)

test(arg1='Bar')

Works with Python 3.x too.

Rob Wouters
  • 15,797
  • 3
  • 42
  • 36