Python函数中的默认参数在哪里

min*_*nel 5 python

我想很多人都看过python的函数接收默认参数.例如:

def foo(a=[]):
    a.append(3)
    return a
Run Code Online (Sandbox Code Playgroud)

如果我们使用foo()调用此函数,则每次调用后输出都会附加整数"3".

定义此函数时,在当前环境中定义名为"foo"的函数对象,此时还会计算默认参数值.每次在没有参数的情况下调用函数时,将根据代码更改评估的参数值.

我的问题是,这个评估参数在哪里存在? 它是在函数对象中还是在调用函数时在方法对象中? 因为python中的所有东西都是一个对象,所以必须有一些地方来保存'a' - > evaluate参数的name-> value绑定.我是否过度思考这个问题?

yak*_*yak 10

正如其他人已经说过的那样,默认值存储在函数对象中.

例如,在CPython中,您可以这样做:

>>> def f(a=[]):
...     pass
...
>>> f.func_defaults
([],)
>>> f.func_code.co_varnames
('a',)
>>>
Run Code Online (Sandbox Code Playgroud)

但是,co_varnames可能包含多个args的名称,因此需要进一步处理,这些属性可能甚至不存在于其他Python实现中.因此,您应该使用该inspect模块来代替您处理所有实现细节:

>>> import inspect
>>> spec = inspect.getargspec(f)
>>> spec
ArgSpec(args=['a'], varargs=None, keywords=None, defaults=([],))
>>>
Run Code Online (Sandbox Code Playgroud)

ArgSpec是一个命名元组,因此您可以将所有值作为属性访问:

>>> spec.args
['a']
>>> spec.defaults
([],)
>>>
Run Code Online (Sandbox Code Playgroud)

正如文档所说,defaults元组总是对应于来自的最后一个参数args.这为您提供了映射.

要创建一个dict,你可以这样做:

>>> dict(zip(spec.args[-len(spec.defaults):], spec.defaults))
{'a': []}
>>>
Run Code Online (Sandbox Code Playgroud)


ber*_*eal 5

它附加到函数对象,请参阅foo.func_defaults

>>> foo()
>>> foo.func_defaults
([3],)
>>> foo()
>>> foo.func_defaults
([3, 3],)
Run Code Online (Sandbox Code Playgroud)

在情况下,如果你想获得的映射a[],你可以访问foo.func_code

defaults = foo.func_defaults
# the args are locals in the beginning:
args = foo.func_code.co_varnames[:foo.func_code.co_argcount] 
def_args = args[-len(defaults):]  # the args with defaults are in the end
print dict(zip(def_args, defaults)) # {'a': []}
Run Code Online (Sandbox Code Playgroud)

(但是,显然,牦牛的版本更好。)

  • 是的,但是正如 OP 所要求的那样,`a` 到 `[]` 的映射在哪里? (2认同)