Python命名空间namespace及作用域原理解析


Posted in Python onJune 05, 2020

曾经学C++的时候,经常听到这个名词,它主要是为了避免命名冲突而产生的。

就像有A(4个苹果),B(6个苹果)两个人,10个苹果,如果只标签了苹果,你无法判断哪个苹果是属于哪个人的,因为标签都是一样的;但是如果标签是A.苹果,B.苹果,那么是不是很容易就知道了苹果是谁的了。

命名空间:提供了一种从名称到对象的映射;主要是通过字典来实现的。

在python中,函数、模块等都有自己的命名空间:

局部命名空间(local namespace):即函数中定义的名称 —— 包括函数中的变量、参数、局部变量等;

全局命名空间(global namespace):即模块中定义的名称 —— 包括模块中的变量、函数、类、参数、常量、导入(import)的模块等;

内置命名空间(built-in namespace):即python内置的名称 —— 包括各种内置函数、Exception等;

而,当python需要使用变量时,会在上述命名空间中依次查找,顺序是:

局部命名空间,全局命名空间、内置命名空间。

同一命名空间中不能有重名,但不同命名空间可以。

可以通过locals()、globals() 函数来获取命名空间的值(字典),在程序的不同位置执行结果不一定一致,因为结果是针对当前位置来说的。

locals()

globals()

Python命名空间namespace及作用域原理解析

可以通过字典形式获取其中的值:

Python命名空间namespace及作用域原理解析

作用域:可以理解为变量所起作用的范围,超出范围则某变量不能被使用。在python 程序中,直接访问一个变量,会从内到外依次访问所有的作用域直到找到,否则报错。Python 中只有模块(module),类(class)以及函数(def、lambda)才会产生新的作用域,其它的代码块(如 if/elif/else/、try/except、for/while等)是不会产生新的作用域的。

作用域可以分为四种:

Local:最内层,包含局部变量,一般指的是函数内部的作用域;

Enclosing:包含非局部但是也不是全局的变量,主要是嵌套时,外层函数的变量,那么相对内层函数来说,嵌套的外层函数中的变量既不是局部变量也不是全局变量。

Global:全局变量,例如当前模块中的全局变量。

Build-in:内置变量。

查找顺序一般是:Local--->Enclosing--->Global--->Build-in

def test1():
  x1 = 1    #Enclosing 作用域
  def test2():
    x2 = 1  #Local 作用域
    print('x2=',x2)
    x1 = 100 #很明显,外层作用域中的x1没有受到影响,因为这里的x1属于Local
    
  test2()
  return x1

aa = test1()
print('aa=',aa)

Python命名空间namespace及作用域原理解析

要想修改外层作用域(上层)的变量,需要用到global和nonlocal关键字。(注意,修改和访问不是一样的程度)

def test1():
  x1 = 1    #Enclosing 作用域
  def test2():
    x2 = 1  #Local 作用域
    print('x2=',x2)
    
    nonlocal x1
    x1 = 100 #通过nonlocal,将这里的x1作用域变化为Enclosing作用域,即影响到Enclosing作用域中的x1的值
    
  test2()
  return x1
aa = test1()
print('aa=',aa)

Python命名空间namespace及作用域原理解析

def test1():
  x1 = 1    # 这个x1属于Enclosing 作用域
  def test2():
    x2 = 1  #Local 作用域
    print('x2=',x2)
    
    global x1  # 这个x1属于全局作用域
    x1 = 100 #这里影响的是全局作用域中的x1值,并不会影响到Enclosing作用域中的值
    
  test2()
  return x1  #返回的是当前作用域Enclosing中的x1的值

aa = test1()
print('aa=',aa)
print('x1=',x1)

Python命名空间namespace及作用域原理解析

全局变量和局部变量

定义在函数内部的变量,拥有局部作用域,属于局部变量。

定义在函数外部的变量,拥有全局作用域,属于全局变量。

全局变量可以在整个全局作用域内访问,但是要修改的话,需要用到global关键字。

更细节一点,若涉及到class:

全局变量:一般在模块内、在所有函数外面、在class外面的变量。

局部变量:一般在函数内、在class的方法内(未加self修饰)的变量。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python类和函数中使用静态变量的方法
May 09 Python
浅谈python 线程池threadpool之实现
Nov 17 Python
对python读取CT医学图像的实例详解
Jan 24 Python
Django框架文件上传与自定义图片上传路径、上传文件名操作分析
May 10 Python
python 函数中的内置函数及用法详解
Jul 02 Python
python matplotlib库绘制条形图练习题
Aug 10 Python
python实现复制大量文件功能
Aug 31 Python
Python解压 rar、zip、tar文件的方法
Nov 19 Python
使用 PyTorch 实现 MLP 并在 MNIST 数据集上验证方式
Jan 08 Python
使用OpenCV获取图像某点的颜色值,并设置某点的颜色
Jun 02 Python
使用TensorBoard进行超参数优化的实现
Jul 06 Python
Python用tkinter实现自定义记事本的方法详解
Mar 31 Python
Python3内置函数chr和ord实现进制转换
Jun 05 #Python
Python 解决相对路径问题:"No such file or directory"
Jun 05 #Python
opencv之颜色过滤只留下图片中的红色区域操作
Jun 05 #Python
Python参数传递及收集机制原理解析
Jun 05 #Python
python如何进行矩阵运算
Jun 05 #Python
Opencv求取连通区域重心实例
Jun 04 #Python
Python中zip函数如何使用
Jun 04 #Python
You might like
用PHP的超级变量$_GET获取HTML表单(Form) 数据
2011/05/07 PHP
js和php邮箱地址验证的实现方法
2014/01/09 PHP
php发送post请求函数分享
2014/03/06 PHP
PHP实现通过二维数组键值获取一维键名操作示例
2019/10/11 PHP
ExtJS 入门
2010/10/29 Javascript
JS的replace方法详细介绍
2012/11/09 Javascript
jquery.cookie() 方法的使用(读取、写入、删除)
2013/12/05 Javascript
js获取select选中的option的text示例代码
2013/12/19 Javascript
javascritp添加url参数将参数加入到url中
2014/09/25 Javascript
详解JavaScript ES6中的模板字符串
2015/07/28 Javascript
如何使用Vuex+Vue.js构建单页应用
2016/10/27 Javascript
vue.js的提示组件
2017/03/02 Javascript
bootstrap datetimepicker 日期插件在火狐下出现一条报错信息的原因分析及解决办法
2017/03/08 Javascript
NodeJS自定义模块写法(详解)
2017/06/27 NodeJs
详解Vue.js搭建路由报错 router.map is not a function
2017/06/27 Javascript
在React中写一个Animation组件为组件进入和离开加上动画/过度效果
2019/06/24 Javascript
微信小程序tab切换可滑动切换导航栏跟随滚动实现代码
2019/09/04 Javascript
基于JavaScript 实现拖放功能
2019/09/12 Javascript
[46:16]2018DOTA2亚洲邀请赛3月30日 小组赛B组 iG VS VP
2018/03/31 DOTA
Python和perl实现批量对目录下电子书文件重命名的代码分享
2014/11/21 Python
Python3操作Excel文件(读写)的简单实例
2019/09/02 Python
Python Pickle 实现在同一个文件中序列化多个对象
2019/12/30 Python
解决TensorFlow模型恢复报错的问题
2020/02/06 Python
如何快速理解python的垃圾回收机制
2020/09/01 Python
如何在 Matplotlib 中更改绘图背景的实现
2020/11/26 Python
一张图片能隐含千言万语之隐藏你的程序代码
2012/12/13 HTML / CSS
迪卡侬英国官网:Decathlon英国
2017/04/08 全球购物
英国豪华家具和经典家居饰品购物网站:OKA
2020/06/05 全球购物
英国Lookfantastic中文网站:护肤品美妆美发购物(英国直邮)
2020/04/27 全球购物
2014法制宣传日活动总结
2014/07/09 职场文书
我为党旗添光彩演讲稿
2014/09/13 职场文书
学校施工安全责任书
2015/01/29 职场文书
党员个人自我评价
2015/03/03 职场文书
长辈生日祝福语大全(72句)
2019/08/09 职场文书
mysql创建存储过程及函数详解
2021/12/04 MySQL
python和Appium的移动端多设备自动化测试框架
2022/04/26 Python