Discuss / Python / 3 solutions to createCounter()

3 solutions to createCounter()

Topic source

回复 用户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的批量赋值一样 也可以用列表批量赋值

lsyjohn

#23 Created at ... [Delete] [Delete and Lock User]

这是因为,当你在当前作用域中的给变量赋值时,该变量将成为该作用域的局部变量,并在外部范围中隐藏任何类似命名的变量

所以在执行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这个变量。

@KonoNA7 n[0]+=1是什么意思呢?

第三种方法为什么要这样子呢

fn = f()

如果直接next(f()),测试会失败,只输出1,1,1,1。如果next(f),就会报错不是迭代器

金钟铉

#26 Created at ... [Delete] [Delete and Lock User]

 createCounter()只在赋给counterA时调用了一次,counterA()调用的是counter(),counterA()再次调用时也是调用counter()

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

ywjco_567

#28 Created at ... [Delete] [Delete and Lock User]

请问第一种方法里,调用后面的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、要学会闭包函数,理解“自由变量”是关键。


Reply