函数的 mutable 对象参数位于何处?有符号table吗? (Python教程4.7.1)

Where does a mutable object argument of a function lives? Is there a symbol table? (Python tutorial 4.7.1)

通过 python tutorial, in section 4.7.1,一个可变的默认参数存储在某处,但我似乎无法使用 dir()globals()locals()f.__dict__。我指的是这段代码:

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

表现为:

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

我希望在函数的命名空间中看到它,比如当我这样做时 dir(f) 但它不在那里。

我看过 this,但这比我想要的要多得多。

它在 f.__defaults__:

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

您没有在 __dict__ 中找到 __defaults__,因为它没有存储在 __dict__ 中;它存储在 dedicated C-level struct member 中,通过函数类型的描述符映射到 __defaults__ 属性。

如果您使用的是 Spyder,当您键入 f. 时,应该会弹出自动完成选项。其中之一是 __defaults__,它包含默认值。

根据 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],)

还有 __kwdefaults__ 关键字参数。

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

请注意 Python 中的内容不一定存储在 可访问 的任何地方。例如,对象的引用计数不能用作属性。只存在于CPython实现的C层,需要builtin magic才能访问

事实上,__defaults__ 也不是 "real" 属性。它是一个内置的 属性 从实现存储它们的任何地方获取默认值。

# python3
>>> type(foo).__defaults__
<attribute '__defaults__' of 'function' objects>
# pypy3
>>>> type(foo).__defaults__
<getset_descriptor object at 0x00000001110adc98>