您的位置:首页 > 编程语言 > Python开发

python global、nonlocal、闭包、作用域——第10天

2020-03-11 12:10 246 查看

今天工作的内容已经完成,于是在公司学习一下午,遇到的闭包作用域的问题一直想不明白,于是问了我们开发他也看了很久才明白(因为他是做java),然后心里想原来并不是所有人都是聪明的,别人 变成优秀的现在就是因为静下心去研究提升。所以自己想转行煎熬的内心又平静而坚定了。

 

一、变量闭包作用域

  python的闭包是如果在一个内部函数里,对外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包

def outer():
x=8
def inner(y):
return x + y
return inner

  下面这个应该是很多人都看过的,但是在我最初看的时候我以为是1,3,9,但是程序运行都是9,debug之后想了好久才明白

  

def count():
fs = []
for i in range(1,4):
def fn():
return i*i
fs.append(fn)
return fs
f1,f2,f3 = count()
print(f1()) #9
print(f2()) #9
print(f3()) #9

因为是fs存了fn这个函数,return i*i 这里的i使用了外部函数for循环里面的i,当调用fn函数的时候,for i 里面的i已经循环变成3, fn函数执行的时候去找变量i是i=3的,所以就都是9

想要把上边的结果变成1,4,9可以使用如下方法:

def count():
def f(j):
def g():
return j*j
return g
fs = []
for i in range(1, 4):
fs.append(f(i)) # f(i)立刻被执行,因此i的当前值被传入f(),每一次的i都会指向一个g的内容地址
return fs

f1,f2,f3 = count()
print(f1()) #1
print(f2()) #4
print(f3()) #922:40:53

下面的代码会报错:UnboundLocalError: local variable 'a' referenced before assignment

a = 10
def bar():
print(a)
a = 'in bar'
bar()

报错的原因是因为python编译的时候发现a局部变量是这样子定义的a = ,没有赋值。

在上面的函数bar中在执行第一条语句的时候,为什么不去访问全局变量a呢这是Python语法的规定,当在函数体中有赋值语句的时候,编译的时候就认为定义了局部变量,从而保证函数封装性

二、global

想要前面的值不报错可以使用global关键字

a = 10
def bar():
global a
a = 'in bar'
bar()
print(a) #in bar

但是使用这种代码得小心了,他很容易改变全局变量的值

三、nonlocal

闭包

def fn():
count = 8
def inner(dt=0):
r =count +dt
print(r) #8
return inner
fn()()

如果上面的代码改动一点点他就会报上面的错:UnboundLocalError: local variable 'a' referenced before assignment,原理是和之前一样的

def fn():
count = 8
def inner(dt=0):
count+=dt
print(count)
return inner
fn()() #会报错

如果想要上面的代码不报错可以使用nonlocal关键字如下:

def fn():
count = 8
def inner(dt=0):
nonlocal count
count =count +dt
print(count)
return inner
fn()() #8

nonlocal关键字使用是,内部函数的变量没有时,可以到外部函数寻找变量。

但是值得注意的是使用nonlocal关键字时,内部函数的变量改变了外部函数的变量也会改变,如下:

name = 'global'
def test():
name = 'local'

def inner_test():
nonlocal name
# global name

name = name + '变量'
return name

print(name) #'local'+'变量'
return inner_test()

print(name) #'global'
print(test())
print(name) #'global'
def funX():
x =5
def funY():
nonlocal x
x+=1
return x
return funY
a = funX()
print(a()) #6
print(a()) #7 因为x+=1已经把外部函数的x改成了6
print(a()) #8

所以我感觉global和nonlocal还是少用的好

                        ——————一条薛定谔的咸鱼

 

 

转载于:https://www.cnblogs.com/venvive/p/11291742.html

  • 点赞
  • 收藏
  • 分享
  • 文章举报
dltk9667 发布了0 篇原创文章 · 获赞 0 · 访问量 160 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: