Variable Scope - Understanding the LEGB rule and global/nonlocal statements

LEGB Scope

Local Enclosing Global Build-in 之所以是这样的先后顺序,是因为在调用变量时,python会自动按照这样的顺序去寻找声明(assignment)

  • local: 局部作用域,指的是变量定义在函数范围内
  • enclosing:
  • global: module or file 最外层的范围(within the main body of the file),或者是使用global关键字,显式定义的变量
  • build-in: python内部已经声明过的变量或者函数名

我们首先先看一下 global和local scope,因为这两个最为常见

global and local

x = "x_global"
def test():
    y = "local y"
    print(y)
test()
local y
x = "x_global"
def test():
    y = "local y"
    print(x)
test()
x_global
  • 在函数内部修改global变量
x = "x_global"
def test():
    global x
    x = "local x" # 这个时候是对global变量操作
    print(x)
test()
print(x)
local x
local x
  • 也可以直接将global变量定义在函数内部
def test():
    global x    # 相当于申明了一个global变量,即使该语句存在于test()函数的内部
    x = "local x" # 
    print(x)
test()
print(x)
local x
local x
  • 总结

虽然这里演示了global变量的使用,但是作者并不推荐大量使用global变量,在我们的程序中。如果使用global变量,我们需要担心这些变量会不会被其他的函数或者代码覆写掉。而如果使用local变量,变量的作用范围只在函数内部,就不用担心我们的变量被其他函数修改。

build-in

just some names pre-assiigned in Python

  • case :min
m = min([2,3,4,1,5])
print(m)
1
import builtins
dir(builtins)
['ArithmeticError',
 'abs',
 'all',
 'any',
 'ascii',
 'bin',
 'bool',
 'bytearray',
 'bytes',
 'callable',
 'chr',
 'classmethod',
 'compile',
 'complex',
 'copyright',
 'credits',
 'delattr',
 'dict',
 ......
 'zip']

global -> build-in

  • python没有阻止我们使用系统内置的这些函数,或者说是关键字作为我们函数或者变量的名称,因此我们可以重新定义这些函数
  • 比如,当我们自己重新定义了min函数后,系统会按照 L-E-G-B的顺序寻找函数的定义,因为我们是在file里直接定义,相当于是global函数,故优先选择执行
def min()
    pass
m = min([2,3,4,1,5])
print(m)
  File "<ipython-input-10-322b8f973710>", line 1
    def min()
             ^
SyntaxError: invalid syntax

Enclosing

def outer():
    x = "outer x"
    def inner():
        x = "inner x"
        print(x)
    inner()
    print(x)

outer()    
inner x
outer x

inner()函数中没有对于x的定义,则其会按照 L-E-G-B的顺序寻找定义,而outer()函数中的local x变量正好作为了inner()中print(x)语句的enclosing 变量,故print的内容相同

def outer():
    x = "outer x"
    def inner():
        # x = "inner x"
        print(x) # local var is not ther anymore ,so go to enclosing scope looking for x
    inner()
    print(x)

outer()    
outer x
outer x
  • 和global、local scope情况一样,在inner()函数中,也可以修改enclosing scope中的变量值,需要通过nonlocal关键字
def outer():
    x = "outer x"
    def inner():
        nonlocal x
        x = "inner x"
        print(x)
    inner()
    print(x)

outer()    
inner x
inner x

总结

  • global local enclosing scope可以分别包含同名变量而互不影响
  • 变量被调用时,寻找定义的顺序是按照 L-E-G-B的顺序寻找
  • 在函数内部及在函数内定义的函数的内部,分别使用global,和nonlocal 关键字可以用来修改global 和enclosing 作用范围内的变量
x = "global x"
def outer():
    x = "outer x"
    def inner():
        x = "inner x"
        print(x)
    inner()
    print(x)

outer()  
print(x)
inner x
outer x
global x

引用

本文主要参考下列视频内容,翻译并亲测代码后形成此文,感谢视频作者的无私奉献!

另外,相关话题的两篇不错的文章推荐

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值