Where is the default parameter in Python function
我想很多人都见过接受默认参数的python函数。例如:
1 2 3 | def foo(a=[]): a.append(3) return a |
如果我们使用foo()调用这个函数,那么每次调用后输出都会附加整数"3"。
定义此函数时,将在当前环境中定义一个名为"foo"的函数对象,此时还将计算默认参数值。每次调用没有参数的函数时,计算的参数值都会根据代码进行更改。
我的问题是,这个被评估的参数在哪里?调用函数时,它是在函数对象中还是在方法对象中?因为python中的所有内容都是一个对象,所以必须有一些地方来保存"a"->计算参数的name->value绑定。我有没有想过这个问题?
正如其他人所说,默认值存储在函数对象中。
例如,在cpython中,您可以这样做:
1 2 3 4 5 6 7 8 | >>> def f(a=[]): ... pass ... >>> f.func_defaults ([],) >>> f.func_code.co_varnames ('a',) >>> |
但是,
1 2 3 4 5 | >>> import inspect >>> spec = inspect.getargspec(f) >>> spec ArgSpec(args=['a'], varargs=None, keywords=None, defaults=([],)) >>> |
1 2 3 4 5 | >>> spec.args ['a'] >>> spec.defaults ([],) >>> |
如文档所述,
要创建dict,可以执行以下操作:
1 2 3 | >>> dict(zip(spec.args[-len(spec.defaults):], spec.defaults)) {'a': []} >>> |
在函数对象中,在
1 2 3 4 5 6 7 | def f(a=[]): a.append(3) print f.func_defaults # ([],) f() print f.func_defaults # ([3],) |
它附加在函数对象上,见
1 2 3 4 5 6 | >>> foo() >>> foo.func_defaults ([3],) >>> foo() >>> foo.func_defaults ([3, 3],) |
如果您想获得
1 2 3 4 5 | 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': []} |
(但显然,牦牛的版本更好。)
它存储在函数对象的
1 2 3 4 | >>> foo.func_defaults ([],) >>> foo() ([3],) |
我发现了一个有趣的情况:在Python2.5.2版本中,尝试使用函数"foo()"
1 2 3 4 5 6 | >>> foo() [1] >>> foo() [1] >>> foo() [1] |
因为调用函数的对象不同:
1 2 3 4 5 6 | >>> id(foo()) 4336826757314657360 >>> id(foo()) 4336826757314657008 >>> id(foo()) 4336826757314683160 |
在2.7.2版本中:
1 2 3 4 5 6 | >>> foo() [1] >>> foo() [1, 1] >>> foo() [1, 1, 1] |
在这种情况下,每次调用函数时对象都是相同的:
1 2 3 4 5 6 | >>> id(foo()) 29250192 >>> id(foo()) 29250192 >>> id(foo()) 29250192 |
这是不同版本的问题吗?