Python 局部变量,全局变量,nonlocal 变量用法

Python 局部变量,全局变量,非局部变量是 Python 三种常见的变量,它们与变量作用域息息相关。

局部变量

一般位于函数内的变量为局部变量,它的作用域仅在函数体内,在函数体外无效:

def foo():
    x = 10
    print(f'x equals {x}' )

foo() # x equals 10
print(x) # error: 'x' is not defined

类似于变量x为局部变量

全局变量

在一个模块中,凡是不在函数体内的变量都是全局变量:

x = "I'm global variable"
def foo():
    x = 10
    print(f'x equals {x}' )

foo() 
print(x) 

打印结果:

x equals 10
I'm global variable

细心的朋友会注意到在函数foo内的变量x打印结果为10,而不是 I'm global variable.

这里面引出一个重要的知识:Python解释器在寻找x时,优先从foo函数体内,也就是局部中寻找,如果找不到,再从全局找。做如下验证:

x = "I'm global variable"
def foo():
    print(f'x equals {x}' )

foo() 
print(x)  # 打印结果为:I'm global variable

因为在局部作用域foo内找不到x,所以往上全局找找到x.

非局部变量

Python解释器起初版本是没有这类变量的,那么后来为什么要添加上这类变量的呢?我们看下面这种场景:

def foo():
    x = 0
    def wrap():
        x += 1
        print(f'x equals {x}')
    for i in range(5):
        wrap()

foo() 

执行函数foo后,在嵌套的函数wrap中抛出如下异常:

local variable 'x' referenced before assignment

意思是局部变量x在使用前未被赋值

这句话本身不难理解,但是问题在于x不是已经在foo函数内已经被赋值了吗,为什么还有上面提示呢?

原因在于:函数内的变量一旦被修改,就会变为局部变量,所以x第一次就出现在等号右侧自然就有问题。

换句话说,如果在wrap内仅仅是读取x,就不会有问题,x被解释为全局变量:

def foo():
    x = 0
    def wrap():
        print(f'x equals {x}')
    for i in range(5):
        wrap()

foo() 

所以,解释器为了解决以上问题,引入了nonlocal关键字,显示的声明x不是局部变量,所以就往外寻找x,然后在foo内被找到:

def foo():
    x = 0
    def wrap():
        nonlocal x
        x += 1
        print(f'x equals {x}')
    for i in range(5):
        wrap()

foo() 

打印结果:

x equals 1
x equals 2
x equals 3
x equals 4
x equals 5

值得注意,nonlocal型变量一般用于函数嵌套中,而自定义的装饰器又会用到嵌套函数,所以nonlocal的价值就体现出来了。

以上就是Python常见的三种变量:局部变量,全局变量,非局部变量的基本介绍。

原创不易,欢迎点赞支持

你可能感兴趣的:(python,twitter,css,ebook,nokia)