函数的局部变量和全局变量

时间:2022-10-25 14:18:10

全局变量与局部变量两者的本质区别就是在于作用域

用通俗的话来理解的话,

全局变量是在整个py文件中声明,全局范围内都可以访问

局部变量是在某个函数中声明的,只能在该函数中调用它,如果试图在超出范围的地方调用,程序就爆掉了

如果在函数内部定义与某个全局变量一样名称的局部变量,就可能会导致意外的效果,可能不是你期望的。因此不建议这样使用,这样会使得程序很不健全

直接来看几个例子来理解全局变量和局部变量的区别吧:

def fun():
    f=1
    # print(f)
    print('>>>:',f)
fun()
print(f)

  运行结果:

>>>: 1
Traceback (most recent call last):
  File "C:/Users/zhang1995/PycharmProjects/day1/day6/day6_txt.py", line 57, in <module>
    print(f)
NameError: name 'f' is not defined

  分析:上面的代码中f是局部变量。而且,整个程序中之定义了一个f变量。在函数内和外,都设定了print(f),来输出f.

从运行结果可以看出。在函数内的print正常执行。print-->1。而外面的print 程序报错,错误原因是:f变量没有定义。所以可以看出,print是无法引用函数里的变量。

# f =100
# def fun():
#     f=1
#     # print(f)
#     def fun1():
#         # f=0
#         # print('---:',f)
#         print('>>>:',f)
#     fun1()
#     print(f)         #如果函数内没有f变量,就向全局变量中寻找,如果有,就输出f
# fun()
# print(f)             #下级局部变量空间没有要引用的值,就向上级空间寻找,但是上级空间不能向下级空间寻找

>>>: 1
1
100

  可以看出:从fun1函数内:当f=0时:print(>>>:)输出的值就是:0.

当fun1内的f没有被定义时,就会去fun1的外部变量域中去寻找。而当f=1存在,所以print(>>>:)输出的就是:1

但是,当在fun中没有f =1时,就会去全局中去寻找,而全局中有f=100,所以,print('>>>"):100。

 

    在Python中,当引用一个变量的时候,对这个变量的搜索是按找本地作用域(Local)、嵌套作用域(Enclosing function locals)、全局作用域(Global)、内置作用域
(builtins模块)的顺序来进行的,即所谓的LEGB规则。 然而当在一个函数内部为一个变量赋值时,并不是按照上面所说LEGB规则来首先找到变量,之后为该变量赋值。在Python中,在函数中为一个变量赋值时,有下面这样一条规则: “当在函数中给一个变量名赋值是(而不是在一个表达式中对其进行引用),Python总是创建或改变本地作用域的变量名,除非它已经在那个函数中被声明为全局变量. ”'''

  所以在嵌套作用于中有可能出现的坑:看下面代码:

def fun():
    num2 = 3

    def fun2():
        num2 *= 2        #当对fun的变量num2进行修改的时候,就还会把num2当作fun2的变量。但是
                                    #fun2中没有定义num2,所以无法进行修改
        print("num2=", num2)
                   #如果是简单的引用,就不会发生判定变量属于下载的变量域
    fun2()
fun()

  发生这种情况就得用到:关键字nonlocal

def fun():
    num2 = 3
    def fun2():
        nonlocal num2
        num2 *= 2
        print("num2=", num2)
        # print(num2)     
    fun2()
fun()

  

num2= 6

  用了nonlocal关键字,就会告诉Python在fun2函数中使用嵌套作用域中的变量num2,因此对变量num2t进行修改时,会直接影响到嵌套作用域中的num2变量,程序最后也就输出6了. 

注意:使用global关键字修饰的变量之前可以并不存在,而使用nonlocal关键字修饰的变量在嵌套作用域中必须已经存在。