python命名空间与作用域

 

命名空间是名称与对象之间的关系,可以将命名空间看做是字典,其中的键是名称,值是对象。

命名空间不共享名称。

在命名空间中的名称能将任何python对象作为值,在不同的命名空间中相同的名称可以与不同的对象相关联。但是,如果存在名称解析协议,则多个命名空间可以一起工作来解析名称。也就是说,如果有多个命名空间(总是有的),那么可以定义搜索的顺序,依次在不同的命名空间里来查找某个名称(或确认其不存在于任何认可的命名空间)。在python中,将这一过程定义为作用域。

作用域搜索规则:LEGB

L:局部的(local)

E:封闭的(Enclosing)

G:全局的(Global)

B:内置的(Built-in)

一、局部命名空间

函数内部的命名空间,在调用函数的时候生成,调用结束时消失。当局部命名空间有效时,它是第一个用于检查某个名字存在性的命名空间。如果在局部命名空间内找到该名称,则返回与名字相关联的对象,反之提示出错。

二、全局命名空间

python在模块中维护命名空间,模块是一些python文件--包含函数等对象,并且可以导入其他程序使用。当某个模块被导入之后,该模块同时引入了一个命名空间,其中包含模块中所有的名称和关联的对象,可以通过存储在没个模块中的__dict__来查看这个命名空间,换句话说,字典就是这个模块的命名空间。

如果想要引用给模块中的对象,要使用点符号将名称和模块名称关联,这实际上是要求将对象与该模块中的名称相关联。

当python启动解释器时,它将自动导入两个模块,即模块__main__和__built-ins__。__main__模块是默认的全局模块,所有新对象都存储在其中。可以通过函数globals来访问该命名空间的字典。子啊平python解释器中通过输入用户交互时,globals是有效的命名空间。

1.局部赋值规则

python中有一种称为“本地赋值”的规则非常有趣。如果在函数内的任何地方进行局部赋值,则该赋值只在当前活动的命名空间中创建名称。有时这将产生副作用,举例如下:

>>> value = 27
>>> def func(param1,param2):
for key,val in locals().items():
print (key,val)
value = value + 1 >>> func(98765,43210)
param1 98765
param2 43210
Traceback (most recent call last):
File "<pyshell#7>", line 1, in <module>
func(98765,43210)
File "<pyshell#6>", line 4, in func
value = value + 1
UnboundLocalError: local variable 'value' referenced before assignment
>>>

首先通过赋值在全局命名空间中创建了变量value。也许你会认为,当函数值加1是会先在局部的命名空间中查找变量,无法找到时在全局命名空间中找到该名字。可以并不是这样。

python提出如下假设,如果在函数体内的任何地方对变量赋值,则python将名称添加到局部命名空间中。语句value=value+1对对象value进行赋值。python假设无论在何处发生赋值,value都是函数func局部命名空间的一部分。当python尝试把1跟value相加时,该value名称在局部命名空间中,但它没有关联值,所以python报错。

问题在于python何时决定使value出现在局部命名空间中。实际value出现在局部命名空间中发生在代码运行前,即,在python运行到函数定义之前。由于创建命名空间时,python会检查代码并填充局部命名空间。在python运行那行代码之前,就发现了对value的赋值,并把它添加到局部命名空间中,当函数执行时,python解释器认为value在局部命名空间中但没有值,所以会产生错误。

2.global语句

有一个方法可以解决上面的问题。如果在函数体内,使用global语句将变量声明为全局变量,那么python不会为该变量在命名空间中创建局部名称。

三、内置模块

遵循LEGB搜索规则,如果python不能在局部命名空间中找到某个名称,则会在全局命名空间中继续寻找,它寻找到的将是python的内置名称。

built-in模块和其他模块一样,都具有__dict__属性,这就是模块的命名空间

四、封闭式变量

“封闭式”的作用域规则适应于函数定义函数时,也就是说,在函数体内定义了一个新的函数。这个函数体内的函数是外函数的局部命名空间中的一部分,意味着只有在外函数执行期间才能够运行。完整的LEGB规则是先检查局部命名空间,之后是封闭在局部命名空间中的其他函数,之后是全局命名空间,在最后以内置命名空间结束。

python命名空间与作用域的更多相关文章

  1. 详解python命名空间和作用域

    1.典型案例 先从几个典型的案例来看下名称空间及作用域对python代码运行的影响,请看下面几个代码实例及其执行结果,是否符合你的预期. 代码1:块作用域 if True: i = 1 print i ...

  2. python命名空间、作用域、闭包与传值传引用

    (以下内容,均基于python3) 最近在看python函数部分,讲到了python的作用域问题,然后又讲了Python的闭包问题. 在做作业的时候,我遇到了几个问题,下面先来看作业. 一. 作业1: ...

  3. python—命名空间、作用域查找顺序、闭包

    名称空间 name space,如下图: x = 1, 1存放在内存中,1 会有一个内存地址,x 则 存放在 name space 里,并同时记录了 1的内存地址, 即 名称空间是存放了变量x与1绑定 ...

  4. Python命名空间和作用域

    准备知识: 1.在Python解释器开始执行之后,机会在内存中开辟一个空间,每当遇到 一个变量的时候,就把变量和值之间的关系记录下来,但是当遇到函数定义 的时候,解释器只是把函数名读入内存,表示这个函 ...

  5. python 命名空间和作用域

    这是python的难点和特点, 有很多的和c/cpp不一样的地方.  它的灵活易用性造成不习惯之处. refer to: http://blog.csdn.net/cc7756789w/article ...

  6. Python进阶 - 命名空间与作用域

    Python进阶 - 命名空间与作用域 写在前面 如非特别说明,下文均基于Python3 命名空间与作用于跟名字的绑定相关性很大,可以结合另一篇介绍Python名字.对象及其绑定的文章. 1. 命名空 ...

  7. [Python] 命名空间&作用域

    Python的类语句不会创建实例 类会创建命名空间,通过对象访问类的属性和方法 类不会创建作用域,对方法和属性的引用必须加以限定(如在方法中必须通过self引用实例的属性) class My1(): ...

  8. Python基础-作用域和命名空间(Scope and Namespace)

    在Python中,对象是独立的,不同作用域中的不同名字都可以被绑定在同一个对象上,当然对这个对象的修改会影响所有的引用.赋值操作就是名字和对象的绑定或重绑定.这和C++中的引用是一样的. 1,基础概念 ...

  9. 【Python 函数对象 命名空间与作用域 闭包函数 装饰器 迭代器 内置函数】

    一.函数对象 函数(Function)作为程序语言中不可或缺的一部分,但函数作为第一类对象(First-Class Object)却是 Python 函数的一大特性. 那到底什么是第一类对象(Firs ...

随机推荐

  1. Python 运维

    1.python解释器提供提供的小工具 1.1 一秒钟启动一个下载服务器 进入要下载文件的目录(shift+鼠标右键可以很快的在当前目录打开一个cmd) python2: python2 -m Sim ...

  2. pwn学习日记Day4 基础知识积累

    知识杂项 *:字符串重复 空指令NOP:\x90 cmp:是比较指令,cmp的功能相当于减法指令.它不保存结果,只是影响相应的标志位. xor:将两个操作数进行异或运算,并将结果存放到操作数1中. s ...

  3. 01-python3.5-模块导入-while-for-range-break-continue

    一.输入用户名和密码----导入getpass模块 #!/usr/bin/env python # -*- coding:utf-8 -*- #Author:XZ """ ...

  4. Jmeter对jar包的调用赋值

    一.前言 在我们测试接口的过程中,可能有时需要用到第三方jar包来生成一些测试数据(如有时需要对参数的输入值使用第三方jar包进行加密操作),涉及到这种的情况,普遍做法是:手动调用jar包获得需要的值 ...

  5. 创建servlet程序知识点详解---servlet-day03

    #1.表单包含有中文参数值,如何处理? ##(1)为什么会有乱码? 表单提交时,浏览器会对中文参数值进行编码/ 注:会按照表单所有的页面打开时所使用的字符集进行编码 比如,浏览器会使用utf-8对中文 ...

  6. 用javaScript获取页面元素值

    用JavaScript获取页面元素常见的三种方法:                                                           getElementById() ...

  7. Windows server 2016安装Docker EE

    Windows server 2016安装Docker EE 下载 windows server 2016 180天评估版本. 地址:https://www.microsoft.com/en-us/e ...

  8. Always clear download 下载 谷歌浏览器插件

    由于该博文不支持上传压缩包,因此,如有需要always clear download插件的可点击此链接在百度网盘上下载https://pan.baidu.com/s/13wWchis3iKqXkIA5 ...

  9. 在 mac iTerm2 中使用 cmd 终端

    在 mac iTerm2 中使用 cmd 终端 主要是因为要在 window 中做一些命令行上的工作, 但又不想切换到整个 window 系统里面去. 在程序和功能中开启 telnet 在服务中启用 ...

  10. windows(xshell)免密码登录

    windows(xshell)免密码登录 第一步生成密钥文件 打开xshell 选个工具栏的工具如下图 选择密钥类型和长度,如下图 密钥会自动生成,如下图,点击下一步即可 设置给密钥加密的密码也可以不 ...