我想很多人都看过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)
它附加到函数对象,请参阅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)
(但是,显然,牦牛的版本更好。)
| 归档时间: |
|
| 查看次数: |
789 次 |
| 最近记录: |