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



请考虑下面的代码。

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的别名存储,即使每次执行循环时都会重新分配I,但它对别名x也无关紧要。

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

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

您在这里创建了一个闭包func2,它使用封闭作用域中的变量i。func2的实例由DEF语句在FOR循环执行时创建。

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

因此,在这段代码中,func1什么都不改变,没有它,结果将是一样的。

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

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返回func1时,i已经绑定在func1中。

执行此操作时:

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

您正在为[0, 1, 2]中的每个i"重新定义"您的func2。生命的最终定义是:

def func2():
    return func1(2)

就这么简单。不幸的是,它的行为并不像你所期望的那样。

最新更新