Discuss / Python / 交作业顺便解疑

交作业顺便解疑

Topic source

烈可烈

#1 Created at ... [Delete] [Delete and Lock User]
def createCounter():
    f = [0]
    print('闭包外--')
    def counter():
        print('闭包内--')
        f[0] = f[0] + 1
        return f[0]
    return counter
 # 测试   
 counterA = createCounter()
 print(counterA(), counterA(), counterA(), counterA(), counterA()) 

输出: 闭包外-- 闭包内-- 闭包内-- 闭包内-- 闭包内-- 闭包内-- 1 2 3 4 5

建议新手这样跑一下,即可知道2个结论: 1)同一个返回函数对象,重复执行的时候,仅跑函数内的内容。返回函数外的内容是跑1次 2)假如是这么写:

def counter():
    print('闭包中--')
    f[0] = f[0] + 1
    return f

print是等内容全部执行完,再输出的。

很简单就可以测试:print(2, 3, 1/0),并不会输出2和3。(没找底层代码,就这么反推出结论不会被打脸吧。。) 那么当都运算完毕,f变量已经存了最后一个值。

反过来假设是f[0],这个不是可变量。

test_number

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

学习了

为什么这样就会报错误呢?

def createCounter():
    f = 0
    print('闭包外--')
    def counter():
        print('闭包内--')
        f = f + 1
        return f
    return counter

报错:

闭包外--
闭包内--
Traceback (most recent call last):
  File "t.py", line 20, in <module>
    print(counterA(), counterA(), counterA(), counterA(), counterA()) 
  File "t.py", line 6, in counter
    f = f + 1
UnboundLocalError: local variable 'f' referenced before assignment

使用nonlocal语句解决直接修改父变量报错问题 ps:nonlocal语句需python3版本

def createCounter():
    f = 0
    print('闭包外--')

    def counter():
        print('闭包内--')
        nonlocal f
        f += 1
        return f
    return counter

运行结果: 闭包外-- 闭包内-- 闭包内-- 闭包内-- 闭包内-- 闭包内-- 1 2 3 4 5

john小师弟

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

为什么会报错啊。。

##内层函数能访问外层函数的变量,但不能修改它的指向

def createCounter():
    count = [0]
    def counter():
        count[0] += 1
        return count[0]
    return counter

##这种情况可行是因为count指向的是一个列表的实例对象,实质上,列表的实例对象的地址一直没变,只是其内容的指向改变了而已

###而nonlocal关键字用来在函数或其他作用域中修改外层(非全局)变量

def createCounter():
    count = 0
    def counter():
        nonlocal count 
        count += 1
        return count
    return counter

###global关键字则是用于修改全局变量

#python引用变量的顺序: 当前作用域局部变量->外层作用域变量->当前模块中的全局变量->python内置变量

你好,我在做本节作业的时候也发现,反复调用返回函数,仅执行闭包内的代码,那么: 这是闭包的特性吗?查了其他博客,这个方面好像都讲的模棱两可; 怎么打破这种规则,再次调用时从闭包外重新运行???(话说大家都怎么在评论里插代码的??) createcounter(): x=0 print('test1=',x) def counter(): nonlocal x x=1+x print('test2=',x) return x return counter countera=createcounter() for a in range(1,4): print(countera(),countera(),countera()) 运算结果: test1= 0 test2= 1 test2= 2 test2= 3 1 2 3 test2= 4 test2= 5 test2= 6 4 5 6 test2= 7 test2= 8 test2= 9 7 8 9

你要重新调用函数Createcounter() 将countera=createcounter() for a in range(1,4): print(countera(),countera(),countera()) 改为 for a in range(1,4): countera=createcounter() print(countera(),countera(),countera())

墨染苍瞳

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

学习了 谢谢大佬

upbeat_peach

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

想请问一下,最后的print内容改成函数名,为何就只跑外面的函数,不跑里面的呢? print(createCounter(),createCounter(),createCounter(),createCounter(),createCounter()) 结果输出是闭包外-- 闭包外-- 闭包外-- 闭包外-- 闭包外-- 闭包外--

<function createCounter.<locals>.counter at 0x0000000002895730> <function createCounter.<locals>.counter at 0x00000000028957B8> <function createCounter.<locals>.counter at 0x0000000002895840> <function createCounter.<locals>.counter at 0x00000000028958C8> <function createCounter.<locals>.counter at 0x0000000002895950>


  • 1
  • 2

Reply