请稍候,加载中....

变量作用域(BGLE)

变量作用域是一个很重要的概念,所谓变量作用域,就是你能访问到变量的范围,比如赋值给变量,从变量读取值。
如果对变量作用域理解错误的话,很有可能导致程序运行出现严重错误。
另外只有理解了变量作用域才能理解闭包函数的用法。

python变量作用域分为四个等级

内置作用域B-Built-in

我们平时在使用代码时,printsummax等等内置函数,都是在内置作用域内,只要解释器一直运行,这些内置函数或者变量就会一直有效,比如TrueFalse,这两个是内置常量标识符,他们的值就是TrueFalse,你不能对TrueFalse赋值,只能获取值
内置作用域其实是通过把内置函数以及内置常量构建在一个叫builtins的模块中,这些内置作用域的变量可以在程序任何地方调用

全局作用域G-Global

全局的概念就是当前代码文件范围内,或者模块内的范围就是全局域,全局域变量在类内部,函数内部都可以获得值,但是不能修改值,一旦修改值,就是另外创建了一个新的局部变量

全局作用域示例

# 全局变量,不在任何的类,函数内部
name = "luxp"

# 可以在函数内部直接访问
def myfun():
    print(name)

def myfun2():
    print(name)
# 输出luxp,函数内部可以直接获得全局变量的值
myfun()
myfun2()

globals()函数

# 打印出所有全局变量
print(globals())

局部作用域L-Local

在python中,局部通常指类内部或者函数内部,以函数举例

# 在函数内部定义的变量只能在函数内部访问
def myfun():
    num = 100
    # num在函数内部可以任意访问
    print(num)

myfun()
# 输出 100

# 这里属于函数外部,所以该条语句无法打印函数内部的num
print(num)

# 函数之间的变量是相互隔离的
def myfun1():
    name = "python-xp.com"
    print(name) #name在函数内部可以任意访问

def myfun2():
    name = "luxp"
    print(name) #name在函数内部可以任意访问
# myfun1与myfun2函数的name互不干扰,两个函数就好像一个个独立的房间一样
myfun1()
myfun2()

locals() - 局部变量收集器

def myfun():
      a = 10
      b = 20
      print(locals())

myfun()

声明全局变量

# 在局部作用域范围内不能直接对全局变量重新赋值
name = "luxp"
def myfun():
    # 尝试修改name的值
    # 实际上定义了一个新的局部域
    name = "python-xp.com"
    print(name)

# 全局域的name
print(name)
# 输出 luxp

# 函数局部域的nanme
myfun()
# 输出 python-xp.com

从输出上可以看到,当myfun内部对name重新赋值后,只在内部生效,全局变量name并没有变化,事实上是在myfun内部创建了一个新的局部变量name

global-声明全局变量

如果想在函数内部修改全局变量,需要在函数内部使用global关键字声明变量

# 全局变量,不在任何的类,函数内部
name = "luxp"
def myfun():
    global name
    name = "python-xp.com"
    print(name)

print(name)
myfun()
print(name)
# 输出
# luxp
# python-xp.com
# python-xp.com

使用global后,就可以在函数内部对g全局变量进行修改了

嵌套作用域E-Enclosing

如果函数内部还有一个内部函数,情况就有些不同,下面这段代码,myfun2称为myfun的嵌套函数

# 对于嵌套函数myfun2来讲
# 外部函数myfun定义的变量可以访问到
# 但是myfun无法访问myfun2的变量,因为myfun2内部的变量只在myfun2内有效
# 相对的, myfun的作用域包含了myfun2
def myfun():
    name = "luxp"
    def myfun2():
        print("myfun2内部:", name)
    myfun2()
    print("myfun:", name)

myfun()
# 输出两次 luxp

myfun2是可以访问myfun定义的变量,但是myfun2内部不能对myfun定义的变量进行修改

# myfun2是可以访问myfun定义的变量,但是myfun2内部不能对myfun定义的变量进行修改
def myfun():
    name = "luxp"
    def myfun2():
        print(name)
        # 添加了给name赋值语句,这时候name就变成了本地的变量,上面的print这一句产生未定义错误
        name = "LUXP"
    myfun2()

# 由于myfun2内部尝试修改非本地变量name报错
myfun()

执行报错:UnboundLocalError: local variable 'name' referenced before assignment

nonlocal - 声明非本地变量

在上例中如果要在myfun2中修改myfunname值,该怎么做呢?

必须声明它为nolocal-非本地变量

def myfun():
    name = "python-xp.com"
    def myfun2():
      # 添加了nolocal声明
        nonlocal name
        print("myfun2内部:", name)
        name = "luxp"
        print("myfun2内部:", name)
    myfun2()
    print("myfun:", name)

myfun()
# 输出:
# python-xp.com
# luxp

从输出上可以看到,使用nonlocal声明后,myfun2不仅可以获得name的值,还可以对name进行修改,此时name的作用域就是嵌套作用域


Python学习手册-