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生成随机数的方法
Jan 14 Python
python re正则表达式模块(Regular Expression)
Jul 16 Python
python中enumerate的用法实例解析
Aug 18 Python
python打开网页和暂停实例
Sep 30 Python
Python基于动态规划算法计算单词距离
Jul 25 Python
深入理解Python中变量赋值的问题
Jan 12 Python
django定期执行任务(实例讲解)
Nov 03 Python
利用TensorFlow训练简单的二分类神经网络模型的方法
Mar 05 Python
Python使用add_subplot与subplot画子图操作示例
Jun 01 Python
python实现简单http服务器功能
Sep 17 Python
Python 下载Bing壁纸的示例
Sep 29 Python
Python中os模块的简单使用及重命名操作
Apr 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求正负数数组中连续元素最大值示例
2014/04/11 PHP
PHP根据session与cookie用户登录状态操作类的代码
2016/05/13 PHP
[原创]PHP实现SQL语句格式化功能的方法
2017/07/28 PHP
背景音乐每次刷新都可以自动更换
2007/02/01 Javascript
JavaScript与函数式编程解释
2007/04/27 Javascript
Uglifyjs(JS代码优化工具)入门 安装使用
2020/04/13 Javascript
javascript结合CSS实现苹果开关按钮特效
2015/04/07 Javascript
JavaScript 里的类数组对象
2015/04/08 Javascript
JS实现先显示大图后自动收起显示小图的广告代码
2015/09/04 Javascript
JavaScript驾驭网页-CSS与DOM
2016/03/24 Javascript
Svg.js实例教程及使用手册详解(一)
2016/05/16 Javascript
jquery实用技巧之输入框提示语句
2016/07/28 Javascript
jQuery实现Select左右复制移动内容
2016/08/05 Javascript
require、backbone等重构手机图片查看器
2016/11/17 Javascript
基于Vue2x的图片预览插件的示例代码
2018/05/14 Javascript
微信小程序动态生成二维码的实现代码
2018/07/25 Javascript
js/jquery遍历对象和数组的方法分析【forEach,map与each方法】
2019/02/27 jQuery
vue v-for循环重复数据无法添加问题解决方法【加track-by='索引'】
2019/03/15 Javascript
判断js数据类型的函数实例详解
2019/05/23 Javascript
vue cli安装使用less的教程详解
2019/07/12 Javascript
[01:35]2018完美盛典章节片——共竞
2018/12/17 DOTA
python中的hashlib和base64加密模块使用实例
2014/09/02 Python
Python实现模拟登录及表单提交的方法
2015/07/25 Python
利用Python中unittest实现简单的单元测试实例详解
2017/01/09 Python
基于Python Numpy的数组array和矩阵matrix详解
2018/04/04 Python
Django 开发调试工具 Django-debug-toolbar使用详解
2019/07/23 Python
python Django的web开发实例(入门)
2019/07/31 Python
详解Django CAS 解决方案
2019/10/30 Python
python利用opencv实现SIFT特征提取与匹配
2020/03/05 Python
使用Keras实现简单线性回归模型操作
2020/06/12 Python
浅谈tensorflow 中的图片读取和裁剪方式
2020/06/30 Python
桥梁工程专业求职信
2014/04/21 职场文书
2014年科协工作总结
2014/12/09 职场文书
病房管理制度范本
2015/08/06 职场文书
javascript拖曳互换div的位置实现示例
2021/06/28 Javascript
利用Java设置Word文本框中的文字旋转方向的实现方法
2021/06/28 Java/Android