Python作用域与名字空间原理详解


Posted in Python onMarch 21, 2020

Python具有静态作用域,变量的作用域由它定义的位置决定,而与调用的位置无关。

 a = 2 
def f():
 a = 2

第一行的a的作用域是全局作用域,作用于定义位置后面的所有位置。

第四行的a的作用域是局部作用域,作用于f函数里。

Python能够形成局部作用域的只有函数与类,其他语句不形成局部作用域。

函数与类的局部作用域

def f():
  a = 1
class A:
  b = 2
if 1 == 1:
  c = 3
for _ in range(1):
  d = 4
while True:
  e = 5
  break
print(c, d, e)
try:
  print(a)
except Exception as e:
  print(e)
try:
  print(b)
except Exception as e:
  print(e)

输出结果

 3 4 5
 name 'a' is not defined
 name 'b' is not defined

python动态运行时,每个作用域都有三个名字空间:由局部变量组成的local名字空间,由全局变量组成的global名字空间,以及python内建模块的builtins名字空间,在查询一个变量时,搜索顺序为local->global->builtins,即局部变量屏蔽全局变量,全局变量屏蔽内建变量。

python的global名字空间是动态的,即每遇到一个赋值语句(def与class也属于赋值语句),global名字空间都可能发生变化。

global名字空间的动态变化

 print(dir())
 a = 1
 print(dir())
 b = 2
 print(dir())

输出结果

1 ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__']
2 ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'a']
3 ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'a', 'b']

从输出结果可以看出,global名字空间是动态增加的。

这意味着,虽然位于global名字空间的变量叫做全局变量,它的作用范围也不是全局位置,它只作用于第一次赋值之后的位置。因为只有在变量赋值初始化的时候,它才会被加入到global名字空间中。

函数和类搜索的global名字空间是调用位置的global名字空间,与定义位置无关

def f():
  print(a)

try:
  f()
except Exception as e:
  print(e)

a = 2
f()

输出结果

name 'a' is not defined
2

函数f打印全局变量a,a在第9行定义。在第五行调用f的时候,a不在global名字空间中,所以会输出错误信息,在第十行再次调用函数f时,a已经加入了global名字空间,所以能够打印出a。

python为了提高效率,local名字空间是静态实现的,因为对于一个函数来说,它所包含的局部变量是明确已知的。

函数的local名字空间是静态的

a = 4
def f():
  try:
    print(a)
  except Exception as e:
    print(e)
  a = 1
f()

输出结果

 local variable 'a' referenced before assignment

在打印a的时候,在local名字空间中找到了a,但是这时候a并没有赋值初始化,所以抛出异常。这也说明了local名字空间与global名字空间不同,它会在一开始就把所有的局部变量加入到名字空间中。

总结:

1. python是静态作用域,变量初始化的位置决定了它的作用域,而与变量调用的位置无关

2. global名字空间是动态的,不同位置的global名字空间不同,local名字空间是静态的,局部变量在整个局部作用域内可见。

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

Python 相关文章推荐
用Python脚本生成Android SALT扰码的方法
Sep 18 Python
python网络编程之UDP通信实例(含服务器端、客户端、UDP广播例子)
Apr 25 Python
Python中用Decorator来简化元编程的教程
Apr 13 Python
使用rst2pdf实现将sphinx生成PDF
Jun 07 Python
使用Python生成XML的方法实例
Mar 21 Python
Django中使用第三方登录的示例代码
Aug 20 Python
python的schedule定时任务模块二次封装方法
Feb 19 Python
Python面向对象程序设计类的封装与继承用法示例
Apr 12 Python
解决Django中调用keras的模型出现的问题
Aug 07 Python
python多线程并发及测试框架案例
Oct 15 Python
python实现监控阿里云账户余额功能
Dec 16 Python
python3 Scrapy爬虫框架ip代理配置的方法
Jan 17 Python
Python小整数对象池和字符串intern实例解析
Mar 21 #Python
Python描述符descriptor使用原理解析
Mar 21 #Python
Python如何省略括号方法详解
Mar 21 #Python
Python如何使用bokeh包和geojson数据绘制地图
Mar 21 #Python
Spring Boot中使用IntelliJ IDEA插件EasyCode一键生成代码详细方法
Mar 20 #Python
python+opencv实现移动侦测(帧差法)
Mar 20 #Python
Java Spring项目国际化(i18n)详细方法与实例
Mar 20 #Python
You might like
php去除HTML标签实例
2013/11/06 PHP
php限制文件下载速度的代码
2015/10/20 PHP
PHP数据库连接mysql与mysqli对比分析
2016/01/04 PHP
PHP图片添加水印功能示例小结
2016/10/03 PHP
php 判断页面或图片是否经过gzip压缩的方法
2017/04/05 PHP
在Javascript中为String对象添加trim,ltrim,rtrim方法
2006/09/22 Javascript
javascript Array数组对象的扩展函数代码
2010/05/22 Javascript
jQuery实现点击图片翻页展示效果的方法
2015/02/16 Javascript
使用JQuery实现智能表单验证功能
2016/03/08 Javascript
浅析JS操作DOM的一些常用方法
2016/05/13 Javascript
浅谈JS原生Ajax,GET和POST
2016/06/08 Javascript
基于js里调用函数时,函数名带括号和不带括号的区别
2016/07/28 Javascript
微信小程序中实现一对多发消息详解及实例代码
2017/02/14 Javascript
解决AngualrJS页面刷新导致异常显示问题
2017/04/20 Javascript
浅谈node中的exports与module.exports的关系
2017/08/01 Javascript
jQuery实现的简单动态添加、删除表格功能示例
2017/09/21 jQuery
js 开发之autocomplete="off"在chrom中失效的解决办法
2017/09/28 Javascript
解决Mac下安装nmp的淘宝镜像失败问题
2018/05/16 Javascript
微信小程序如何获取手机验证码
2018/11/04 Javascript
Webpack中SplitChunksPlugin 配置参数详解
2020/03/24 Javascript
[01:42]TI4西雅图DOTA2前线报道 第一顿早饭哦
2014/07/08 DOTA
Python实现抓取页面上链接的简单爬虫分享
2015/01/21 Python
Golang与python线程详解及简单实例
2017/04/27 Python
Django使用HttpResponse返回图片并显示的方法
2018/05/22 Python
python实现朴素贝叶斯算法
2018/11/19 Python
Python实现字典排序、按照list中字典的某个key排序的方法示例
2018/12/18 Python
python实现定时压缩指定文件夹发送邮件
2020/12/22 Python
PySide2出现“ImportError: DLL load failed: 找不到指定的模块”的问题及解决方法
2020/06/10 Python
推荐WEB开发者最佳HTML5和CSS3代码生成器
2015/11/24 HTML / CSS
Sql面试题
2013/03/20 面试题
人力资源主管岗位职责
2014/01/29 职场文书
酒店管理专业自荐信
2014/05/23 职场文书
应届生求职信
2014/05/31 职场文书
文明社区申报材料
2014/08/21 职场文书
管理人员岗位职责
2015/02/14 职场文书
紫日观后感
2015/06/05 职场文书