python 中的命名空间,你真的了解吗?


Posted in Python onAugust 19, 2020

写在之前

命名空间,又名 namesapce,是在很多的编程语言中都会出现的术语,估计很多人都知道这个词,但是让你真的来说这是个什么,估计就歇菜了,所以我觉得 “命名空间” 有必要了解一下。

全局变量 & 局部变量

全局变量和局部变量是我们理解命名空间的开始,我们先来看一段代码:

x = 2
def func():
  x = 3
  print('func x ---> ',x)

func()
print('out of func x ---> ',x)

这段代码输出的结果如下:

func x ---> 3
out of func x ---> 2

从上述的结果中可以看出,运行 func(),输出的是 func() 里面的变量 x 所引用的对象 3,之后执行的是代码中的最后一行。这里要区分清楚,前一个 x 输出的是函数内部的变量 x,后一个 x 输出的是函数外的变量 x,两个变量互相不影响,在各自的作用域中起作用。

那个只在函数内起作用的变量就叫 “局部变量”,有了 “局部” 就有相应的 “全部”,但是后者听起来有歧义,所以就叫了 “全局”。

x = 2
def func():
  global x = 3 #注意此处
  print('func x ---> ',x)

func()
print('out of func x ---> ',x)

这段代码中比上段代码多加了一个 global x,这句话的意思是在声明 x 是全局变量,通俗点说就是这个 x 和 函数外的 x 是同一个了,所以结果就成了下面这样:

func x ---> 3
out of func x ---> 3

这样乍一看好像全局变量好强,可以管着函数内外,但是我们还是要注意,全局变量还是谨慎使用的好,因为毕竟内外有别,不要带来混乱。

作用域

作用域,用比较直白的方式来说,就是程序中变量与对象存在关联的那段程序,比如我在上面说的, x = 2 和 x = 3 是在两个不同的作用域中。

通常的,作用域是被分为静态作用域和动态作用域,虽然我们说 Python 是动态语言,但是它的作用域属于静态作用域,即 Python 中的变量的作用域是由该变量所在程序中的位置所决定的。

在 Python 中作用域被划分成四个层级,分别是:local(局部作用域),enclosing(嵌套作用域),global(全局作用域)和 built - in(内建作用域)。对于一个变量,Python 也是按照之前四个层级依次在不用的作用域中查找,我们在上一段代码中,对于变量 x,首先搜索的是函数体内的局部作用域,然后是函数体外的全局作用域,至于这段话具体怎么来理解,请看下面的例子:

def out_func():
  x = 2
  def in_func():
    x = 3
    print('in_func x ---> ',x)
  in_func()
  print('out_func x ---> ',x)

x = 4
out_func()
print('x == ',x)

仔细观察一下上面的代码和运行的结果,你就会发现变量在不同的范围内进行搜索的规律,是不是感觉这些都是以前被你忽略的呢?

命名空间

《维基百科》中说 “命名空间是对作用域的一种特殊的抽象”,在这里我用一个比方来具体说明一下:

比如张三在公司 A,他的工号是 111,李四在公司 B,他的工号也是 111,因为两个人在不同的公司,他们俩的工号可以相同但是不会引起混乱,这里的公司就表示一个独立的命名空间,如果两个人在一个公司的话,他们的工号就不能相同,否则光看工号也不知道到底是谁。

其实上面举的这个例子的特点就是我们使用命名空间的理由,在大型的计算机程序中,往往会出现成百上千的标识符,命名空间提供隐藏区域标识符的机制。通过将逻辑上相关的标识符构成响应的命名空间,可以使整个系统更加的模块化。

我在开头引用的《维基百科》的那句话说 “命名空间是对作用域的一种特殊的抽象”,它其实包含了处于该作用域内的标识符,且它本身也用一个标识符来表示。在 Python 中,命名空间本身的标识符也属于更外层的一个命名空间,所以命名空间也是可以嵌套的,它们共同生活在 “全局命名空间” 下。

简言之,不同的命名空间可以同时存在,但是彼此独立,互不干扰。当然了,命名空间因为其对象的不同也有所区别,可以分为以下几种:

1.本地命名空间:模块中有函数或者类的时候,每个函数或者类所定义的命名空间即是本地命名空间,当函数返回结果或者抛出异常的时候,本地命名空间也就结束了。

2.全局命名空间:每个模块创建了自己所拥有的全局命名空间,不同模块的全局命名空间彼此独立,不同模块中相同名称的命名空间也会因为模块的不同而不相互干扰。

3.内置命名空间:当 Python 运行起来的时候,它们就存在了,内置函数的命名空间都属于内置命名空间,所以我们可以在任何程序中直接运行它们。

程序查询命名空间的时候也有一套顺序,依次按照本地命名空间 ,全局命名空间,内置命名空间。

def fun(like):
  name = 'rocky'
  print(locals())

fun('python')

访问本地命名空间使用 locals 完成,我们来看一下结果:

{'name': 'rocky', 'like': 'python'}

从上面的结果中可以看出,命名空间中的数据存储的结构和字典是一样的。可能你已经猜到了,当我们要访问全局命名空间的时候,可以使用 globals。

关于命名空间还有一个生命周期的问题,就是一个命名空间什么时候出现,什么时候消失,这个很好理解,就是哪部分被读入内存,哪部分的命名空间就存在了,比如我们在上面说的,Python 启动,内置命名空间就建立。

写在之后

至此,我的零基础学习 Python 计划里关于函数的部分就结束了,这一部分写的时间超出了我原本的计划,但是在写的过程中觉得有些知识点还是说说的好,从下周开始,就要开始 “类” 这一部分的学习啦,希望我们还可以继续这么走下去,我坚持写,你也坚持学。

还有坚持。。点个赞。。

以上就是python 中的命名空间,你真的了解吗?的详细内容,更多关于python 命名空间的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
python实现rest请求api示例
Apr 22 Python
Python XML RPC服务器端和客户端实例
Nov 22 Python
在树莓派2或树莓派B+上安装Python和OpenCV的教程
Mar 30 Python
python中的全局变量用法分析
Jun 09 Python
Python随机生成均匀分布在单位圆内的点代码示例
Nov 13 Python
CentOS7.3编译安装Python3.6.2的方法
Jan 22 Python
python读取txt文件并取其某一列数据的示例
Feb 19 Python
深入浅析Python 中 is 语法带来的误解
May 07 Python
python集合的创建、添加及删除操作示例
Oct 08 Python
Python 余弦相似度与皮尔逊相关系数 计算实例
Dec 23 Python
Matplotlib绘制混淆矩阵的实现
May 27 Python
Python 装饰器(decorator)常用的创建方式及解析
Apr 24 Python
13个Pandas实用技巧,助你提高开发效率
Aug 19 #Python
python环境搭建和pycharm的安装配置及汉化详细教程(零基础小白版)
Aug 19 #Python
Python实现自动签到脚本的示例代码
Aug 19 #Python
python3环境搭建过程(利用Anaconda+pycharm)完整版
Aug 19 #Python
Python容器类型公共方法总结
Aug 19 #Python
python3将变量输入的简单实例
Aug 19 #Python
手把手教你将Flask应用封装成Docker服务的实现
Aug 19 #Python
You might like
一段防盗连的PHP代码
2006/12/06 PHP
smarty+adodb+部分自定义类的php开发模式
2006/12/31 PHP
php 分页类 扩展代码
2009/06/11 PHP
PHP中STDCLASS用法实例分析
2016/11/11 PHP
PHP实现限制IP访问及提交次数的方法详解
2017/07/17 PHP
JavaScript DOM学习第一章 W3C DOM简介
2010/02/19 Javascript
基于jQuery实现图片的前进与后退功能
2013/04/24 Javascript
推荐一个自己用的封装好的javascript插件
2015/01/29 Javascript
JS控制弹出新页面窗口位置和大小的方法
2015/03/02 Javascript
Javascript中的getUTCDay()方法使用详解
2015/06/10 Javascript
谈谈Jquery ajax中success和complete有哪些不同点
2015/11/20 Javascript
详解能在多种前端框架下使用的表格控件
2017/01/11 Javascript
Vue 2.0 服务端渲染入门介绍
2017/03/29 Javascript
Vue2.0 从零开始_环境搭建操作步骤
2017/06/14 Javascript
教你用Cordova打包Vue项目的方法
2017/10/17 Javascript
vue脚手架搭建项目的兼容性配置详解
2018/07/17 Javascript
layDate日期控件使用方法详解
2018/11/15 Javascript
jQuery实现的点击图片居中放大缩小功能示例
2019/01/16 jQuery
TypeScript开发Node.js程序的方法
2019/04/30 Javascript
JavaScript RegExp 对象用法详解
2019/09/24 Javascript
微信小程序实现录音功能
2019/11/22 Javascript
基于javascript处理二进制图片流过程详解
2020/06/08 Javascript
[03:12]完美世界DOTA2联赛PWL DAY6集锦
2020/11/05 DOTA
python赋值操作方法分享
2013/03/23 Python
python异步任务队列示例
2014/04/01 Python
pycharm中使用anaconda部署python环境的方法步骤
2018/12/19 Python
django主动抛出403异常的方法详解
2019/01/04 Python
python 控制台单行刷新,多行刷新实例
2020/02/19 Python
python 8种必备的gui库
2020/08/27 Python
python文件排序的方法总结
2020/09/13 Python
Python 实现二叉查找树的示例代码
2020/12/21 Python
Expedia挪威官网:酒店、机票和租车
2018/03/03 全球购物
CK加拿大官网:Calvin Klein加拿大
2020/03/14 全球购物
怎样比较两个类型为String的字符串
2016/08/17 面试题
2019学子的答谢词范本!
2019/07/05 职场文书
MySQL一劳永逸永久支持输入中文的方法实例
2022/08/05 MySQL