python3 global和nonlocal 关键字_Python关键字:global和nonlocal

结论

global和nonlocal在局部声明变量,表明变量的定义不在块内,而在全局/上级局部作用域内。

global

先谈一下Python的引用查找循序:

先在当前局部作用域找声明,如果找不到,到上层(包括全局)找

举一个例子:

a = 1

def foo():

b = a

return b

print(foo())

程序输出 1。foo()内部没有定义1,它向上层找到了全局变量a。

稍微修改:

a = 1

def foo():

b = a

a = 2 # newline

return b

print(foo())

程序报错:UnboundLocalError: local variable 'a' referenced before assignment

因为这次a在foo()内部声明了,但使用先于声明,是错误的。

再改一下:

a = 1

def foo():

global a # newline

b = a

a = 2

return b

print(foo())

正常输出1。global关键字声明,foo()中的a即是全局变量a,后面的都是赋值语句。

nonlocal

nonlocal的功能和global类似,只是nonlocal声明的变量在上级局部作用域内,而不是全局定义。

上面的代码中,将global改为nonlocal:

a = 1

def foo():

nonlocal a

b = a

a = 1

return b

print(foo())

报错:SyntaxError: no binding for nonlocal 'a' found。表明nonlocal不能声明全局变量。

将foo包裹在上层局部作用域中:

def foo_upper():

a = 1

def foo():

nonlocal a

b = a

a = 1

return b

print(foo())

foo_upper()

正常输出1

nonlocal应用:闭包

利用nonlocal可以实现Python的闭包。

比如:

def adder():

num = 0

def add():

nonlocal num

num += 1

return num

return add

add = adder()

print(add())

print(add())

print(add())

print(add())

打印出了:1 2 3 4

或者,实现一个单例函数(不能同时执行多次)装饰器:

def singlecase(fn):

'装饰器:单例模式'

running = False

@functools.wraps(fn)

def wrapper(*args, **kargs):

nonlocal running

if running:

raise Exception('单例函数 ' + fn.__name__ + ' 已经在执行')

running = True

try:

return fn(*args, **kargs)

finally:

running = False

return wrapper

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值