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求解平方根的方法
Mar 11 Python
Python2.x版本中cmp()方法的使用教程
May 14 Python
Python计算三维矢量幅度的方法
Jun 15 Python
python获取元素在数组中索引号的方法
Jul 15 Python
使用turtle绘制五角星、分形树
Oct 06 Python
Django文件上传与下载(FileFlid)
Oct 06 Python
Centos7 下安装最新的python3.8
Oct 28 Python
python 遗传算法求函数极值的实现代码
Feb 11 Python
PyCharm中Matplotlib绘图不能显示UI效果的问题解决
Mar 12 Python
python 绘制国旗的示例
Sep 27 Python
Python利用matplotlib绘制散点图的新手教程
Nov 05 Python
关于pytest结合csv模块实现csv格式的数据驱动问题
May 30 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 5.0对象模型深度探索之属性和方法
2008/03/27 PHP
使用bcompiler对PHP文件进行加密的代码
2010/08/29 PHP
Yii操作数据库的3种方法
2014/03/11 PHP
高性能PHP框架Symfony2经典入门教程
2014/07/08 PHP
php 读取输出其他文件的实现方法
2016/07/26 PHP
Laravel Memcached缓存驱动的配置与应用方法分析
2016/10/08 PHP
Laravel5.7 Eloquent ORM快速入门详解
2019/04/12 PHP
跟我一起学写jQuery插件开发方法(附完整实例及下载)
2010/04/01 Javascript
Jquery中getJSON在asp.net中的使用说明
2011/03/10 Javascript
分享一个asp.net pager分页控件
2012/01/04 Javascript
js新闻滚动 js如何实现新闻滚动效果
2013/01/07 Javascript
文本域中换行符的替换示例
2014/03/04 Javascript
NodeJS Express框架中处理404页面一个方式
2014/05/28 NodeJs
JavaScript中通过提示框跳转页面的方法
2016/02/14 Javascript
Angularjs2不同组件间的通信实例代码
2017/05/06 Javascript
解决iview打包时UglifyJs报错的问题
2018/03/07 Javascript
Javasript设计模式之链式调用详解
2018/04/26 Javascript
vue keep-alive实现多组件嵌套中个别组件存活不销毁的操作
2020/10/30 Javascript
Windows安装Python、pip、easy_install的方法
2017/03/05 Python
Python实现二维数组按照某行或列排序的方法【numpy lexsort】
2017/09/22 Python
python实现用户答题功能
2018/01/17 Python
python清除字符串中间空格的实例讲解
2018/05/11 Python
Python 读取串口数据,动态绘图的示例
2019/07/02 Python
python找出因数与质因数的方法
2019/07/25 Python
pycharm如何使用anaconda中的各种包(操作步骤)
2020/07/31 Python
HTML5 video播放器全屏(fullScreen)方法实例
2015/04/24 HTML / CSS
乌克兰移动电子产品和相关配件的在线商店:iTMag
2020/03/16 全球购物
年终考核评语
2014/01/19 职场文书
DIY手工制作经营店创业计划书
2014/02/01 职场文书
企业仓管员岗位职责
2014/06/15 职场文书
大四学生个人总结
2015/02/15 职场文书
员工辞职信怎么写
2015/02/27 职场文书
计生个人工作总结
2015/02/28 职场文书
Nginx中break与last的区别详析
2021/03/31 Servers
深入理解margin塌陷和margin合并的解决方案
2021/06/26 HTML / CSS
Python 中的 copy()和deepcopy()
2021/11/07 Python