交作业顺便解疑
Topic source为什么这样就会报错误呢?
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
##内层函数能访问外层函数的变量,但不能修改它的指向
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())
想请问一下,最后的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
烈可烈
输出:
闭包外-- 闭包内-- 闭包内-- 闭包内-- 闭包内-- 闭包内-- 1 2 3 4 5
建议新手这样跑一下,即可知道2个结论: 1)同一个返回函数对象,重复执行的时候,仅跑函数内的内容。返回函数外的内容是跑1次 2)假如是这么写:
很简单就可以测试:
print(2, 3, 1/0)
,并不会输出2和3。(没找底层代码,就这么反推出结论不会被打脸吧。。) 那么当都运算完毕,f变量已经存了最后一个值。反过来假设是
f[0]
,这个不是可变量。