2

Going through the python tutorial, in section 4.7.1, a mutable default argument is stored somewhere but I can't seem to find it using dir(), globals(), locals() or f.__dict__. I'm referring to this code:

def f(a, L=[]):
    L.append(a)
    return L

behaves as:

>>> print(f(1))
[1]
>>> print(f(2))
[1, 2]
>>> print(f(3))
[1, 2, 3]

I would expect to see this in the namespace of the function, say when I do dir(f) but it is not there.

I had a look at this but this is way more than I'm probably looking for.

user3325563
  • 187
  • 2
  • 12

3 Answers3

3

It's in f.__defaults__:

>>> def f(a, L=[]):
...     L.append(a)
...     return L
...
>>> f.__defaults__
([],)

You didn't find __defaults__ in __dict__ because it's not stored in the __dict__; it's stored in a dedicated C-level struct member, which is mapped to the __defaults__ attribute by a descriptor on the function type.

user2357112
  • 260,549
  • 28
  • 431
  • 505
3

As per the Python Data Model:

__defaults__ A tuple containing default argument values for those arguments that have defaults, or None if no arguments have a default value

>>> def foo(a=[]):
...    a.append(1)
...
... foo()
... foo.__defaults__
([1],)

There is also __kwdefaults__ for keyword-only arguments.

>>> def foo(a=1, *, b=2):
...     pass
...
... foo.__defaults__, foo.__kwdefaults__
((1,), {'b': 2})

Note that things in Python are not necessarily stored anywhere accessible. For example, the reference count of an object is not available as an attribute. It only exists in the C layer of the CPython implementation and requires builtin magic to access.

In fact, __defaults__ is not a "real" attribute either. It is a builtin property fetching the defaults from wherever the implementation stores them.

# python3
>>> type(foo).__defaults__
<attribute '__defaults__' of 'function' objects>
# pypy3
>>>> type(foo).__defaults__
<getset_descriptor object at 0x00000001110adc98>
MisterMiyagi
  • 44,374
  • 10
  • 104
  • 119
0

If you're using Spyder, when you type f., autocomplete options should pop up. One of them is __defaults__, which holds the defaults.

Acccumulation
  • 3,491
  • 1
  • 8
  • 12