python中全局变量和局部变量详解

3,285 阅读3分钟

写在最前面:  

python中全局变量和局部变量的最大区别在于局部变量只能通过函数去访问,而全局变量可以直接访问。

 !!! 

我们先来看一个最简单的例子,事实上这并不是一个真正的全局变量,只是在类中的一个变量。 

 !!! 

 我们先从类中的变量访问开始讲起 那么我们要如何访问这个变量呢?

class variable:
    a = '我是类变量'
 
    def showvarible(self):
        b = '我是函数变量'
        print(a)
        print(b)
 
 
variable().showvarible()

毫无疑问,编译器就已经报错了,这是因为类中的变量不可以在函数中直接访问,应该这样

class variable:
    a = '我是类变量'
 
    def showvarible(self):
        b = '我是函数变量'
        print(variable.a)
        print(b)
 
 
variable().showvarible()

我是类变量
我是函数变量

其实我们还可以通过self去访问

class variable:
 
    a = '我是类变量'
 
    def showvarible(self):
        b = '我是函数变量'
        print(self.a)
        print(b)
 
 
variable().showvarible()


结果是一样的

我是类变量
我是函数变量

还可以怎么做呢,我们通过构造函数给定一个参数,类中可访问

class variable:
 
    def __init__(self,a):
        self.a = '我是类变量'
 
    def showvarible(self):
        b = '我是函数变量'
        print(self.a)
        print(b)
        
 
 
variable(1).showvarible()

我是类变量
我是函数变量

 这里需要注意的是,实例化的时候必须给参数,由于python是动态语言,不需要指定参数的类型,你可以放int,比如1,也可以给一个字符串。

然后我们真正看一下全局变量

a = '我是真正的全局变量'
 
 
def showvariable():
    b = '我一直都是局部变量'
    print(a)
    print(b)
 
 
showvariable()

我是真正的全局变量
我一直都是局部变量

当我们试图在函数外访问这个函数的局部变量时

a = '我是真正的全局变量'
 
 
def showvariable():
    b = '我一直都是局部变量'
    print(a)
 
def showb():
    print(b)
 
 
showvariable()

报错

我是真正的全局变量
Traceback (most recent call last):
  File "F:/leetcode/xxx.py", line 13, in <module>
    showb()
  File "F:/leetcode/xxx.py", line 9, in showb
    print(b)
NameError: name 'b' is not defined

说明局部变量只能在局部使用。

那么不巧的是,我的局部变量和全局变量定义了同一个名称,谁的优先级更高呢?

a = '我是真正的全局变量'
 
 
def showvariable():
    a = '我一直都是局部变量'
    print(a)
 
 
print(a)
showvariable()

果然,函数优先使用了局部变量

而优先级还有一个体现,来看下面的例子

a = 3
 
 
def showvariable():
    a = a * 5
    print(a)
 
 
showvariable()

你可能会认为输出15,但是上面的一个例子告诉我们,在函数内会优先使用局部变量

3
Traceback (most recent call last):
  File "F:/leetcode/xxx.py", line 10, in <module>
    showvariable()
  File "F:/leetcode/xxx.py", line 5, in showvariable
    a = a * 3
UnboundLocalError: local variable 'a' referenced before assignment

这样是因为,我们在函数内定义了一个局部变量a,但是还没来得及赋值,就被*5,编译器不知道拿谁去*5,当然报错了。

下面讲讲global,global第一次是只能定义不能赋值的

def showvariable():
    global a
    a = '我是global'
    print(a)
 
 
showvariable()

我是global

当然是可以在函数外访问的

def showvariable():
    global a
    a = '我是global'
    print(a)
 
def showglobal():
    print(a)
 
showvariable()
showglobal()

我是global
我是global

但是,必须赋值后才有意义,如果像这样

def showvariable():
    global a
    a = '我是global'
    print(a)
 
def showglobal():
    print(a)
 
print(a)
showvariable()
showglobal()

在没有赋值的时候,就去打印

Traceback (most recent call last):
  File "F:/leetcode/xxx.py", line 9, in <module>
    print(a)
NameError: name 'a' is not defined

因为此时global a还没有赋值,当然不能打印。