python参数实际上是参数的别名吗?

时间:2016-04-16 06:22:09

标签: python function parameters arguments alias

请考虑以下代码。

a = []

def func1(x):
    return x

for i in range(3):
    def func2():
        return func1(i)

    a.append(func2)

for k in range(3):
    print(a[k]())

打印出来

2
2
2

http://gestaltrevision.be/wiki/python/aliases(上一节)和http://gestaltrevision.be/wiki/python/functions_basics中'范围'部分的'使用别名',我了解到函数参数实际上是传递的参数的别名。

因此,在

def func1(x): return x

for i in range(3):
    def func2(): return func1(i)

我推断,因为x将被存储为i的别名,即使每次执行循环时都重新分配,它的别名x也无关紧要。

所以我希望前三行输出0,1,2而不是2,2,2。

你能解释一下我在这里做错了什么吗?感谢

3 个答案:

答案 0 :(得分:2)

你在这里创建一个闭包func2,它使用封闭范围内的变量i。 func2的实例是在FOR循环执行时由DEF语句创建的。

然后在退出FOR循环后执行func2。 在python中,循环变量在循环退出后不会被销毁。 因此,在退出循环时,闭包使用封闭范围中i的当前值。

所以在这段代码中,func1什么都没有改变,如果没有它,结果就会一样。

答案 1 :(得分:2)

如果您希望代码以您希望的方式工作,请执行以下操作

def func2(i): 
    def func1():
        return i
    return func1

a = [func2(i) for i in range(3)]
for k in range(3): 
    print(a[k]()) # prints 0 1 2

现在,为什么你的代码没有工作?好吧,它与对象绑定到闭包中的名称时有关,func1是。在您的代码中,参数xfunc1在运行时被绑定。因此,a中的每个函数都有func1(i)且打印时i的值为2,所以你得到所有2.所以解决方案是在编译时绑定它,即func2 1}}返回func1i已绑定在func1

答案 2 :(得分:0)

执行此操作时:

for i in range(3):
    def func2():
        return func1(i)

你重新定义" func2中每i[0, 1, 2]。生活的最终定义是:

def func2():
    return func1(2)

就这么简单。不幸的是,它的表现并不像你期望的那样。