[Python] 变量名的四个作用域及 nonlocal 关键字

Python 变量名的四个作用域及 nonlocal 关键字

变量访问顺序

Python访问一个变量时,其查找顺序遵循变量解析机制LEGB法则,依次搜索:局部作用域、嵌套作用域、全局作用域、以及内置作用域。

  • L:local,局部作用域,即函数中定义的变量;
  • E:enclosing,嵌套的父级函数的局部作用域,即包含此函数的上级函数的局部作用域,但不是全局的;
  • G:global,全局变量,就是模块级别定义的变量;
  • B:built-in,系统固定模块里面的变量,比如int, bytearray等。 搜索变量的优先级顺序依次是:作用域局部>外层作用域>当前模块中的全局>python内置作用域,也就是LEGB。

1. 局部作用域:

def fun():
    def inner():
        var = 'b'
        print(var)

    inner()
    print(var)	# 报错了,var 只在 inner 局部作用域内生效

fun()

2. 嵌套作用域:

var = 'a'
def fun():
    var = 'b'
    def inner():
        print(var)	# b,此时去嵌套作用域搜索到了 var

    inner()
    print(var)	# b

fun()
print(var)	# a

3. 全局作用域

我们来看以下代码:

var = 'a'

def fun():
    def inner():
        var = 'c'
        print(var)	# c  搜索局部作用域
        
    inner()
    print(var)	# a  即便你没有定义 var,Python还是找到了它,因为去搜索了全局作用域
    
fun()
print(var)	# a

如果我们试图修改全局的 var 会怎么样呢?

var = 'a'

def fun():
    var = 'b'	# 这样相当于定义了一个新的变量,不会去搜索全局作用域

    def inner():
        var = 'c'
        print(var)	# c

    inner()
    print(var)	# b	

fun()
print(var)	# a,没有修改成功

如果你要修改全局变量,你需要加上global关键字:

var = 'a'

def fun():
    global var	# 使用 global
    var = 'b'

    def inner():
        var = 'c'
        print(var)	# c

    inner()
    print(var)	# b

fun()
print(var)	# b 全局变量被修改了

4. 内置作用域

Python 内置的模块 __builtin__,我们平时使用的内置函数就来自于它。

print(abs)	# <built-in function abs>
print(max)	# <built-in function max>

5. nonlocal 的使用

先看一段代码:

def fun():
    var = 'b'	# 如果我想在 inner 里修改 var,怎么办呢?

    def inner():
        var = 'c'
        print(var)	# c	局部作用域

    inner()
    print(var)	# b 没变化

fun()

这样不行啊,如果使用 global 呢?

def fun():
    var = 'b'

    def inner():
        global var
        var = 'c'
        print(var)	# c

    inner()
    print(var)	# b 没变化


fun()

还是不行,这就让人有些头疼了。不过别担心,使用 nonlocal 就好了啊。

def fun():
    var = 'b'

    def inner():
        nonlocal var
        var = 'c'
        print(var)	# c

    inner()
    print(var)	# c 变了,它变了!

fun()
  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值