3 solutions to createCounter()
Topic source这是因为,当你在当前作用域中的给变量赋值时,该变量将成为该作用域的局部变量,并在外部范围中隐藏任何类似命名的变量。
所以在执行i = 1 + i
的时候。因为i被重新赋值了,所以i的作用域编程counter函数范围。同时将它原来在createCounter函数范围的同名变量i消除。然后,执行1 + i的时候就出错了,此时i还没有定义呢!所以报错:UnboundLocalError: local variable 'i' referenced before assignment
。
按前面拿笔小星的说法,如果直接在conter()函数中对createCounter函数中的变量直接赋值,会因为作用域的问题,造成局部变量覆盖createCounter中的变量,后续调用conter()函数时,该变量就会出现没定义的报错。而如果在createCounter定义的是列表,如
li = [0]
而在conter()中,赋值语句为
li[0] += 1
即只是修改了li这个列表的第一个元素的值,但是li这个列表变量本身的指向没有发生变化,因此后续调用conter()函数时,仍然可以直接使用li这个变量。
def count(): def f(j): def g(): return j * j return g fs = [] for i in range(1, 4): fs.append(f(i)) return fs
楼主,能帮忙看下廖雪峰老师这个代码,该怎么理解呀?想不出这个过程怎么走的。走到最后
f1, f2, f3 = count()f1()f2()f3()
结果都为9
请问第一种方法里,调用后面的counterA()的时候,li为什么不会再定义为0?.......
def createCounter1():
li = [0]
def counter():
li[0] += 1
return li[0]
return counter
因为:createCounter1是个闭包函数。
1、li = [0] 定义了一个列表(li[0] == 0),这个列表是个容器,在counter函数里执行li[0] += 1,则函数外的li[0] 也会增加 1;
2、函数引用了li列表: 这个li是“局部作用域以外且非全局作用域当中的变量”----自由变量。(https://docs.python.org/zh-cn/3.7/reference/simple_stmts.html#nonlocal)
3、闭包函数在return li[0]后,会保留着li的值,供下次使用。
4、要学会闭包函数,理解“自由变量”是关键。
用户5318353752
回复 用户7041329703
#5 Created at 3-21 17:31 我想问下,前面的 f1, f2, f3 为什么能带入;或者说这里的1、2、3怎么会带入到函数内的;fs又不是函数,它是list不是,list要带入不得这样的吗 f[1];
谢谢,前面那个讲解也没看明白
f1 = fs[0]
f2 = fs[1]
f3 = fs[2]
和tuple的批量赋值一样 也可以用列表批量赋值