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

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

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

在python中,变量查找遵循LGB原则,即优先在局部作用域(local scope)中对变量进行查找,失败则在全局作用域(global scope)中进行查找,最后尝试再内建作用域(build-in scope)内查找,如果还是未找到的话,则抛出异常。后来由于闭包和嵌套函数的出现,作用域又增加了外部作用域,这样变量的查找作用域优先级变为:局部、外部、全局和内建。 作用域由def、class、lambda等语句产生,if、try、for等语句并不会产生新的作用域。变量名引用分为三个作用域进行查找:首先是本地,然后是函数内(如果有的话),之后是全局,最后是内置。在默认情况下,变量名赋值会创建或者改变本地变量。全局声明将会给映射到模块文件内部的作用域的变量名赋值。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能够改变变量作用域的代码段是defclass、lamda.

    2. def scopetest():

    3. localvar=6;

    4. print(localvar)

    5. scopetest()

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

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

    8. while True:

    9. newvar=8

    10. print(newvar)

    11. break;

    12. print(newvar)

    13. try:

    14. newlocal=7

    15. raise Exception

    16. except:

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

    18. 输出结果:8 8 7

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

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

    21. def scopetest():

    22. var=6;

    23. print(var)#

    24. var=5

    25. print(var)

    26. scopetest()

    27. print(var)

    28. 输出结果:5 6 5

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

    30. def scopetest():

    31. global var

    32. var=6;

    33. print(var)#

    34. var=5

    35. print(var)

    36. scopetest()

    37. print(var)

    38. 输出结果:5 6 6

    39. 再看一种这种情况:

    40. def scopetest():

    41. var=6;

    42. print(var)#

    43. def innerFunc():

    44. print(var)#look here

    45. innerFunc()

    46. var=5

    47. print(var)

    48. scopetest()

    49. print(var)

    50. 输出结果:5 6 6 5

python——变量作用域及嵌套作用域的更多相关文章

  1. python tips:最内嵌套作用域规则,闭包与装饰器

    在作用域与名字空间提到,python是静态作用域,变量定义的位置决定了变量作用的范围.变量沿着local,global,builtins的路径搜索,直觉上就是从里到外搜索变量,这称为最内嵌套作用域规则 ...

  2. Python变量、赋值及作用域

    ## 变量 - 指向唯一内存地址的一个名字 - 目的是为了更方便地引用内存中的值 - 可以使用id(变量)函数来查看变量的唯一id值,若两者id值相同,则表示两个变量指向同一地址,两个变量的值完全相同 ...

  3. python全栈开发_day11_作用域,函数嵌套和闭包

    一:作用域 1)什么是作用域 作用域是规定一个变量可以作用的范围,运行和销毁的范围 2)作用域的分类 1.内置作用域built_in:随着解释器的运行而产生,解释器运行的终止而销毁. 2.全局作用域g ...

  4. python(一):作用域

    与c相比,python作用域很奇特. 在Python中变量的作用域是由它在源代码中的位置决定的,这一点与c相似. python只支持4种作用域,即局部作用域,全局作用域,内置作用域,嵌套作用域. 比较 ...

  5. Python变量作用域(一)

    在一个程序中使用变量名时,Python创建.改变或者查找变量名都是在所谓的命名空间中进行的.作用域指的就是命名空间. Python中的变量名在第一次赋值时已经创建,并且必须经过赋值后才能够使用.由于变 ...

  6. Python——day11 函数(对象、名称空间、作用域、嵌套、闭包)

    一.函数对象  函数名就是存放了函数的内存地址,存放了内存地址的变量都是对象,即 函数名 就是 函数对象  函数对象的应用 1. 可以直接被引用  fn = cp_fn 2 .可以当作函数参数传递 c ...

  7. Python之函数--命名空间、作用域、global、nonlocal、函数的嵌套和作用域链

    命名空间 -------‘’存放名字与值的关系”的空间 代码在运行伊始,创建的存储“变量名与值的关系”的空间叫做全局命名空间: 在函数的运行中开辟的临时的空间叫做局部命名空间. 命名空间一共分为三种: ...

  8. python函数作用域,嵌套函数,闭包

    函数作用域                                                                                                ...

  9. Python函数学习——作用域与嵌套函数

    全局与局部变量 在函数中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量. 全局变量作用域是整个程序,局部变量作用域是定义该变量的函数. 当全局变量与局部变量同名时,在定义局部变量的函数内 ...

随机推荐

  1. 将GDB中的输出定向到文件

    1 set args >output.log 三种方法,一种通过tee在启动时重定向: 1 gdb |tee -a file 第二种在run时加入: 1 run <input.txt &g ...

  2. 流畅的python第九章笔记 python风格的python

    9.1对象表示形式 __repr__和__str__这两个方法都是用于显示的,__str__是面向用户的,而__repr__面向程序员. 我们打印下面的A是默认输出这个对象的类型,我们对B进行了修改_ ...

  3. 如何使用python查看视频的长度

    import subprocess import re def get_length(filename): result = subprocess.Popen(["ffprobe" ...

  4. 配置OpenResty支持SSL(不受信任的证书)

    #关闭防火墙 chkconfig iptables off service iptables stop #关闭SELINUX sed -i 's/SELINUX=enforcing/SELINUX=d ...

  5. MVC5 ModelState

    ModelState.IsValid 总是false的原因 在做添加功能的时候,发现这个IsValid总是false,这个是它自己的验证机制. 因为是添加,就是说主键是自增的,添加的时候不需要指定这个 ...

  6. Java IO 学习(六)Java的Direct Memory与IO

    ByteBuffer的源码中有这样一段注释: A byte buffer is either direct or non-direct. Given a direct byte buffer, the ...

  7. ==与equals()区别

    equals和==的区别? 经常被简单的理解为equals方法用来比较两个对象是否相同, 而==比较运算符用来比较两个基本数据类型的数值是否相同. 这样的理解无可厚非,但还要透过简单看看本质,才会更清 ...

  8. Python的网络编程[1] -> FTP 协议[1] -> 使用 pyftplib 建立 FTP 服务器

    使用 pyftplib 建立 FTP 服务器 pyftplib 主要用于建立 FTP Server,与 ftplib 建立的 Client 进行通信. 快速导航 1. 模块信息 2. 建立 FTP 服 ...

  9. 数学【p2117】 小z的矩阵

    题目描述-->p2117 小z的矩阵 分析: 题目给定我们一个正方形. 容易想到,正方形是对称的. 推敲一下 如果我们的矩阵是这样的↓ 闭眼瞎敲出来的. \[\begin{bmatrix} {0 ...

  10. [CF623E]Transforming Sequence

    $\newcommand{\align}[1]{\begin{align*}#1\end{align*}}$题意:对于一个序列$a_{1\cdots n}(a_i\in[1,2^k-1])$,定义序列 ...