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. test6

  2. 2019年度【计算机视觉&机器学习&人工智能】国际重要会议汇总

    简介 每年全世界都会举办很多计算机视觉(Computer Vision,CV). 机器学习(Machine Learning,ML).人工智能(Artificial Intelligence ,AI) ...

  3. Python基础(一)常用函数

    1.map() 此函数可以,将列表内每一个元素进行操作,并返回列表 原型 map(function,[list]) def fc(x): return x * 2 print(map(fc,[1,2, ...

  4. K8S的网络接口CNI及灵雀云的实践

    K8S的网络模型 我们从底层网络来看,分为三个层面.首先是Pod之间的多个容器的网络互通.我们知道,K8S的Pod可以由多个容器组成,这个层面网络互通是比较简单的,因为所有的容器都是共享一个网卡,可以 ...

  5. linux和Windows下用sublime text3编译运行C,C++

    安装MinGW 1.首先安装MinGW,默认安装位置是C:\MinGW. 2.安装完成后,右键“我的电脑”->属性 ->高级->环境变量,在系统环境变量PATH里添加C:\MinGW ...

  6. [openjudge-贪心]装箱问题

    题目描述 描述 一个工厂制造的产品形状都是长方体,它们的高度都是h,长和宽都相等,一共有六个型号,他们的长宽分别为1*1, 2*2, 3*3, 4*4, 5*5, 6*6.这些产品通常使用一个 6*6 ...

  7. jdk1.8新特性之lambda表达式及在Android Studio中的使用举例

    Jdk1.8已经出很久了但是很多同学对它的特性在android studio 中的应用可能还不是很熟悉,今天我们就来对这个新特性在AS中做它的应用实践. 一.首先在有JDK1.8的情况下我们要在AS的 ...

  8. Python+OpenCV图像处理(十六)—— 轮廓发现

    简介:轮廓发现是基于图像边缘提取的基础寻找对象轮廓的方法,所以边缘提取的阈值选定会影响最终轮廓发现结果. 代码如下: import cv2 as cv import numpy as np def c ...

  9. ftp权限设置大全!!!

    1.登录和对匿名用户的设置write_enable=YES                         //是否对登录用户开启写权限.属全局性设置.默认NOlocal_enable=YES    ...

  10. 基于Docker的GoldenGate部署

    前言 Docker最近几年异常火爆,主要是因为其方便.快捷.轻量,相对于VM,它不需要占用太多资源,随时可以创建.删除,或在已有image上添加一些软件,再制作成另一个模板image供日后使用.Doc ...