zoukankan      html  css  js  c++  java
  • 3.3.3 变量作用域

      变量起作用的代码范围称为变量的作用域,不同作用域内同名变量之间互不影响,就想不同文件夹的同名文件之间互不影响一样。一个变量在函数外部定义和在函数内部定义,其作用域是不同的,函数内部定义的变量一般为局部变量,在函数外部定义的变量为全局变量。

      在函数内部定义的普通变量只在该函数内起作用,当函数运行结束后,在其内部定义的局部变量将被自动删除而不可访问。在函数内部定义的全局变量当函数结束以后仍然存在并且可以访问。

      如果想要在函数内部修改一个定义在函数外的变量值,那么这个变量就不能是局部的,其作用域必须是全局的。可以在函数内部通过global关键字来声明或定义全局变量,这分两种情况:

      (1)一个变量已在函数外定义,如果在函数内需要修改这个变量的值,并将这个赋值结果反映到函数之外,可以在函数内部用global明确声明要使用已定义的同名全局变量。

      (2)在函数内部直接使用global关键字将一个变量声明为全局变量,如果在函数外没有定义该全局变量,在调用这个函数之后,会自动增加新的全局变量。

      或者说,也可以这样理解:

        <1>在函数内如果值引用某个变量的值而没有为其赋新值,该变量为(隐式的)全局变量;

        <2>如果在函数内任意位置有为变量赋值的操作,该变量即被认为是(隐式的)局部变量,除非在函数内显式地用global进行声明。

      下面的代码演示了局部变量和全局变量的用法。

     1 >>> def demo():
     2     global x       #声明或创建全局变量
     3     x = 3          #修改全局变量的值
     4     y = 4          #局部变量
     5     print('全局变量:{}  局部变量:{}'.format(x,y))
     6 
     7     
     8 >>> x = 5          #在函数外部定义了全局变量 x
     9 >>> demo()
    10 全局变量:3  局部变量:4
    11 >>> 
    12 >>> x
    13 3
    14 >>> y              #尝试着在函数外部访问一下函数的局部变量
    15 Traceback (most recent call last):
    16   File "<pyshell#11>", line 1, in <module>
    17     y              #尝试着在函数外部访问一下函数的局部变量
    18 NameError: name 'y' is not defined
    19 >>> 
    20 >>> del x          #删除在函数外部定义的全局变量
    21 >>> 
    22 >>> x              #尝试访问一下全局变量 x
    23 Traceback (most recent call last):
    24   File "<pyshell#15>", line 1, in <module>
    25     x              #尝试访问一下全局变量 x
    26 NameError: name 'x' is not defined
    27 >>> 
    28 >>> demo()         #再调用一次函数,该函数会声明全局变量哦
    29 全局变量:3  局部变量:4
    30 >>> 
    31 >>> x              #在函数内部创建了全局变量x
    32 3
    33 >>> 
    34 >>> y              #局部变量在函数调用结束后自动删除
    35 Traceback (most recent call last):
    36   File "<pyshell#21>", line 1, in <module>
    37     y
    38 NameError: name 'y' is not defined
    39 >>> 

      如果局部变量与全局具有相同的名字,那么改局部变量会在自己的作用域内隐藏同名的全局变量,例如下面的代码所演示。

     1 >>> def demo():
     2     x = 3     #创建了局部变量,并自动隐藏了同名的全局变量
     3     print(x)
     4 
     5     
     6 >>> x = 5  #创建全局变量
     7 >>> x
     8 5
     9 >>> 
    10 >>> demo()
    11 3
    12 >>> x       #函数调用后,不影响全局变量 x 的值
    13 5
    14 >>> 
    15 
    16 # 个人理解:
    17 # 局部变量的作用范围是函数体内,即使和全局变量同名了,在函数体内修改局部变量的值,也不会影响全局变量的值
    18 
    19 # 在函数外修改全局变量的值,不会影响函数体内局部变量的值

       最后,如果需要在同一个程序的不同模块之间共享全局变量,可以编写一个专门的模块来实现这一目的。例如,假设在模块A.py中有如下变量定义:

        global_variable = 0

      而在模块B.py中使用以下语句修改全局变量的值:

        import A

        A.global_variable = 1

      在模块C.py中使用以下语句来访问全局变量的值:

        import A

        print(A.global_variable )

        

      小提示:

        (1)一般而言,局部变量的引用比全局变量速度快,应优先考虑使用;

        (2)应尽量避免过多使用全局变量,因为全局变量会增加不同函数之间的隐式耦合度,降低代码可读性,并使得代码测试和纠错变得很困难。

      拓展知识:局部变量的空间是在栈上分配的,而栈空间是由操作系统维护的,每当调用一个函数时,操作系统会为其分配一个栈帧,函数调用结束后立刻释放这个栈帧。因此,函数调用结束后,该函数内部所有的局部变量都不再存在。

      拓展知识:除了局部变量和全局变量,Python还支持nonlocal关键字定义一种介于两者之间的变量。例如下面代码:

     1 def scope_test():
     2 
     3     def do_local():
     4         spam = '我是局部变量'
     5 
     6     def do_nonlocal():
     7         nonlocal spam        #这时要求spam必须是已存在的变量
     8         spam='我不是局部变量,也不是全局变量'
     9 
    10     def do_global():
    11         global spam          #如果全局作用域内没有spam,就自动创建一个
    12         spam = '我是全局变量'
    13 
    14     spam = '原来的值'
    15     do_local()
    16     print('局部变量赋值后:',spam)
    17     do_nonlocal()
    18     print('nonlocal变量赋值后:',spam)
    19     do_global()
    20     print('全局变量赋值后',spam)
    21 
    22 
    23 scope_test()
    24 print('全局变量:',spam)
    25 
    26 #局部变量赋值后: 原来的值
    27 #nonlocal变量赋值后: 我不是局部变量,也不是全局变量
    28 #全局变量赋值后 我不是局部变量,也不是全局变量
    29 #全局变量: 我是全局变量
    30 
    31 #哈哈,感觉这个nonlocal就是用在嵌套函数中的,用于在子函数和父函数之间传递变量值的。而local是用于父函数和模块之间传递变量值的。这一点需要知道。
  • 相关阅读:
    实验二 20159213
    读书笔记二 20159213
    读书随笔 20159213
    keycode对照表
    jquery ajax中各个事件执行顺序如下
    移动端web开发技巧
    zepto处理touch事件
    CSS控制文字只显示一行,超出部分显示省略号
    input按钮的事件处理大全
    jquery中ajax处理跨域的三大方式
  • 原文地址:https://www.cnblogs.com/avention/p/8610967.html
Copyright © 2011-2022 走看看