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 相关文章推荐
使用graphics.py实现2048小游戏
Mar 10 Python
Python中使用ElementTree解析XML示例
Jun 02 Python
Python实现的密码强度检测器示例
Aug 23 Python
python如何拆分含有多种分隔符的字符串
Mar 20 Python
[原创]windows下Anaconda的安装与配置正解(Anaconda入门教程)
Apr 05 Python
Python爬虫信息输入及页面的切换方法
May 11 Python
python 中字典嵌套列表的方法
Jul 03 Python
Python random模块制作简易的四位数验证码
Feb 01 Python
Python3 获取文件属性的方式(时间、大小等)
Mar 12 Python
Python自动化办公Excel模块openpyxl原理及用法解析
Nov 05 Python
python 管理系统实现mysql交互的示例代码
Dec 06 Python
Python基本的内置数据类型及使用方法
Apr 13 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
推荐Discuz!5的PHP代码高亮显示与实现可运行代码
2007/03/15 PHP
php根据一个给定范围和步进生成数组的方法
2015/06/19 PHP
javascript调试说明
2010/06/07 Javascript
10个基于浏览器的JavaScript调试工具分享
2013/02/07 Javascript
JS中prototype关键字的功能介绍及使用示例
2013/07/21 Javascript
jquery.mobile 共同布局遇到的问题小结
2015/02/10 Javascript
JavaScript实现图片DIV竖向滑动的方法
2015/04/25 Javascript
Uploadify上传文件方法
2016/03/16 Javascript
javascript中不易分清的slice,splice和split三个函数
2016/03/29 Javascript
js阻止浏览器默认行为的简单实例
2016/05/15 Javascript
仅一个form表单 js实现注册信息依次填写提交功能
2016/06/12 Javascript
jquery中的常见问题及快速解决方法小结
2016/06/14 Javascript
手机端 HTML5使用photoswipe.js仿微信朋友圈图片放大效果
2016/08/25 Javascript
浅谈移动端之js touch事件 手势滑动事件
2016/11/07 Javascript
bootstrap-datetimepicker实现只显示到日期的方法
2016/11/25 Javascript
浅谈在vue中用webpack打包之后运行文件的问题以及相关配置方法
2018/02/21 Javascript
JS闭包原理与应用经典示例
2018/12/20 Javascript
开发中常用的25个JavaScript单行代码(小结)
2019/06/28 Javascript
Jquery 动态添加元素并添加点击事件实现过程解析
2019/10/12 jQuery
Vue2.x-使用防抖以及节流的示例
2021/03/02 Vue.js
在Python的Django框架中创建语言文件
2015/07/27 Python
Python3从零开始搭建一个语音对话机器人的实现
2019/08/23 Python
Pandas聚合运算和分组运算的实现示例
2019/10/17 Python
TensorFlow实现从txt文件读取数据
2020/02/05 Python
python读取图片的几种方式及图像宽和高的存储顺序
2020/02/11 Python
HTML 5 input placeholder 属性如何完美兼任ie
2014/05/12 HTML / CSS
洛杉矶健身中心女性专用运动服饰品牌:Marika
2018/05/09 全球购物
Boden澳大利亚官网:英国在线服装公司
2018/08/05 全球购物
香港演唱会订票网站:StubHub香港
2019/10/10 全球购物
Java程序员面试90题
2013/10/19 面试题
数控加工专业毕业生自荐信
2013/09/27 职场文书
求职简历自我评价范例
2014/03/12 职场文书
买房委托公证书
2014/04/08 职场文书
国际金融专业自荐信
2014/07/05 职场文书
保密工作整改报告
2014/11/06 职场文书
使用javascript解析二维码的三种方式
2021/11/11 Javascript