zoukankan      html  css  js  c++  java
  • python——变量作用域及嵌套作用域

    ----------------------------------------------------------------------------- 前言------------------------------------------------------------------------------

    Python 的变量名解析机制也称为 LEGB 法则,具体如下:当在函数中使用未确定的变量名时,Python 搜索 4 个作用域:本地作用域(L),之后是上一层嵌套结构中 def 或 lambda 的本地作用域(E),之后是全局作用域(G),最后是内置作用域(B)。按这个查找原则,在第一处找到的地方停止。如果没有找到,Python 会报错的。

    -----------------------------------------------------------------------------正文-----------------------------------------------------------------------------

    python中,变量查找遵循LGB原则,即优先在局部作用域(local scope)中对变量进行查找,失败则在全局作用域(global scope)中进行查找,最后尝试再内建作用域(build-in scope)内查找,如果还是未找到的话,则抛出异常。后来由于闭包和嵌套函数的出现,作用域又增加了外部作用域,这样变量的查找作用域优先级变为:局部、外部、全局和内建。 作用域由defclasslambda等语句产生,iftryfor等语句并不会产生新的作用域。变量名引用分为三个作用域进行查找:首先是本地,然后是函数内(如果有的话),之后是全局,最后是内置。在默认情况下,变量名赋值会创建或者改变本地变量。全局声明将会给映射到模块文件内部的作用域的变量名赋值。Python 的变量名解析机制也称为 LEGB 法则,具体如下:当在函数中使用未确定的变量名时,Python 搜索 4 个作用域:本地作用域(L),之后是上一层嵌套结构中 def lambda 的本地作用域(E),之后是全局作用域(G),最后是内置作用域(B)。按这个查找原则,在第一处找到的地方停止。如果没有找到,Python 会报错的。

    [python]

    1. a = 1  

    2. def f():  

    3.       a = 2  

    4. def g():  

    5.        print a //[1]:输出结果为2  

    6. return g  

    7. func = f()  

    8. func()//[2]  




        
    代码的[2]处调用的函数实际上调用的是函数f 中定义的内嵌函数g,在代码 的[1]处,函数g 内的“print a”的输出结果为2。初看上去有些疑问,因为函数f 内的约束“a = 2”在其之外应该是不起作用的,当执行func()时,起作用的约束应该是“a = 1”才对。但是我们之前说到了,作用域仅仅是由文本决定的,函数g 位于函数f 之内,所以函数g 定义的作用域内嵌于函数f 的作用域之内。换句话说,函数f 的作用域是函数g 的作用域的直接外围作用域,所以,按照最内嵌套作用域规则,[1]处的名字引用应该引用的是函数f 定义的作用域中所创建的约束。

    尽管在代码清单8-2 [2]处,“a = 2”这个约束已经不起作用了,但是Python 在执行“func = f()”时,会执行函数f 中的“def g():”语句,这时Python 会将约束“a = 2”与函数g 对应的函数对象捆绑在一起,将捆绑后的结果返回,这个捆绑起来的整体被称为“闭包”。

         
    实际上这里有一个相当微妙的问题,最内嵌套作用域规则是“闭包”的结果呢,还是“闭包”是最内嵌套作用域规则的实现方案?这两个问题看上去是一致的,但却隐含着谁决定谁的关系。实际上,Python 实现闭包是为了实现最内嵌套作用域规则。换句话说,最内嵌套作用域规则是语言设计时的设计策略,即是形而上的“道”;而闭包则实现语言时的一种方案,即是形而下的“器”。
      

    [python] 

      1. python能够改变变量作用域的代码段是defclasslamda.  

      2.   

      3.     def scopetest():    

      4.         localvar=6;    

      5.         print(localvar)    

      6.           

      7.     scopetest()    

      8.     #print(localvar) #去除注释这里会报错,因为localvar是本地变量    

      9.   

      10.     if/elif/elsetry/except/finallyfor/while  

      11.   

      12.     while True:    

      13.         newvar=8    

      14.         print(newvar)    

      15.         break;    

      16.         

      17.     print(newvar)    

      18.         

      19.     try:    

      20.         newlocal=7    

      21.         raise Exception    

      22.     except:    

      23.         print(newlocal)#可以直接使用哦    

      24.   

      25. 输出结果:8 8 7  

      26.   

      27. 可见这个关键字中定义变量,他们的作用域跟外部是一致的,这个跟Java的作用域概念有点不一样。  

      28.   

      29.     变量搜索路径是:本地变量->全局变量  

      30.   

      31.     def scopetest():    

      32.         var=6;    

      33.         print(var)#    

      34.             

      35.     var=5     

      36.     print(var)    

      37.     scopetest()    

      38.     print(var)    

      39.   

      40. 输出结果:5 6 5  

      41.   

      42. 这里var 首先搜索的是本地变量,scopetest()中 var=6相当于自己定义了一个局部变量,赋值为6. 当然如果的确要修改全局变量的值,则需要如下:  

      43.   

      44.     def scopetest():    

      45.         global var     

      46.         var=6;    

      47.         print(var)#    

      48.             

      49.     var=5     

      50.     print(var)    

      51.     scopetest()    

      52.     print(var)    

      53.   

      54. 输出结果:5 6 6  

      55.   

      56. 再看一种这种情况:  

      57.   

      58.     def scopetest():    

      59.         var=6;    

      60.         print(var)#    

      61.         def innerFunc():    

      62.             print(var)#look here    

      63.         innerFunc()    

      64.             

      65.     var=5     

      66.     print(var)    

      67.     scopetest()    

      68.     print(var)    

      69.   

      70. 输出结果:5 6 6 5  

  • 相关阅读:
    Ubuntu 更换软件源
    Ubuntu 配置 SOCKS5
    Ubuntu 配置 Sha-dow-socks
    frp(内网穿透)
    solr 远程代码执行(CVE-2019-12409)
    多线程处理爬虫
    python实现文件自动排序
    python 实现根据文件名自动分类移动至不同的文件夹
    Centos7如何开启任意端口服务
    centos7默认安装没有连接网络
  • 原文地址:https://www.cnblogs.com/Simon-xm/p/3913983.html
Copyright © 2011-2022 走看看