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

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. Dinic算法学习&&HDU2063

    http://www.cnblogs.com/SYCstudio/p/7260613.html 看这篇博文懂了一点,做题再体会体会吧 找了好久都没找到一个好用的模板…… 我也是佛了..最后决定用峰神的 ...

  2. OpenCV 2.4.9 学习笔记(3)—— OpenCV自动为输出数组(矩阵)分配内存

    OpenCV大部分时候会为OpenCV方法中的输出数据(方法的参数)自动分配内存,所以如果一个方法的参数有一个或者多个输入数组(cv::Mat 实例)和一些输出数组时,OpenCV会自动为输出数组分配 ...

  3. (计数器)NOIP模拟赛(神奇的数位DP题。。)

    没有原题传送门.. 手打原题QAQ [问题描述]     一本书的页数为N,页码从1开始编起,请你求出全部页码中,用了多少个0,1,2,…,9.其中—个页码不含多余的0,如N=1234时第5页不是00 ...

  4. (wifi)wifi移植之命令行调试driver和supplicant

    前言 小弟从事android wifi framework部分开发已经有一年的时间了,虽然感觉什么都没有学习到,但是回想起刚接手android wifi时候的那份无知,其实肚子里面还是有点东西的,本着 ...

  5. docker 解决:Get http:///var/run/docker.sock/v1.19/version: dial unix /var/run/docker.sock: no such file or directory. Are you trying to connect to a TLS-enabled daemon without TLS?

    docker 安装之后,通过命令查看docker相关信息时,可能会出现错误:Get http:///var/run/docker.sock/v1.19/version: dial unix /var/ ...

  6. windows 中使用hbase 异常:java.io.IOException: Could not locate executable null\bin\winutils.exe in the Hadoop binaries.

    平时一般是在windows环境下进行开发,在windows 环境下操作hbase可能会出现异常(java.io.IOException: Could not locate executable nul ...

  7. poj 1389(离散化+计算几何)

    Area of Simple Polygons Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3412   Accepted ...

  8. 51nod 1004 n^n的末位数字【快速幂】

    1004 n^n的末位数字 题目来源: Author Ignatius.L (Hdu 1061) 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题  收藏  关注 给出 ...

  9. Python的扩展接口[2] -> 动态链接库DLL[1] -> 组件对象模型 COM 的 Python 调用

    组件对象模型 COM 的 Python 调用 关于COM的基本概念,可参考组件对象模型 COM的内容,下面主要介绍两种使用 Python 调用 COM 组件的方法. 1 使用 win32com 1.1 ...

  10. 洛谷——P1614 爱与愁的心痛

    题目背景 (本道题目隐藏了两首歌名,找找看哪~~~) <爱与愁的故事第一弹·heartache>第一章 <我为歌狂>当中伍思凯神曲<舞月光>居然没赢给萨顶顶,爱与愁 ...