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 相关文章推荐
用C++封装MySQL的API的教程
May 06 Python
python黑魔法之参数传递
Feb 12 Python
浅析Python基础-流程控制
Mar 18 Python
详细分析python3的reduce函数
Dec 05 Python
Python二进制串转换为通用字符串的方法
Jul 23 Python
python中实现控制小数点位数的方法
Jan 24 Python
django-rest-framework 自定义swagger过程详解
Jul 18 Python
使用Pyhton集合set()实现成果查漏的例子
Nov 24 Python
Pytorch训练过程出现nan的解决方式
Jan 02 Python
浅谈Pytorch中的自动求导函数backward()所需参数的含义
Feb 29 Python
python中使用input()函数获取用户输入值方式
May 03 Python
浅析python连接数据库的重要事项
Feb 22 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
WIN98下Apache1.3.14+PHP4.0.4的安装
2006/10/09 PHP
PHP获取文件绝对路径的代码(上一级目录)
2011/05/29 PHP
PHP 杂谈《重构-改善既有代码的设计》之五 简化函数调用
2012/05/07 PHP
关于PHP模板Smarty的初级使用方法以及心得分享
2013/06/21 PHP
请离开include_once和require_once
2013/07/18 PHP
php mysql_real_escape_string函数用法与实例教程
2013/09/30 PHP
php file_get_contents抓取Gzip网页乱码的三种解决方法
2013/11/12 PHP
PHP中exec与system用法区别分析
2014/09/22 PHP
PHP进程同步代码实例
2015/02/12 PHP
四个常见html网页乱码问题及解决办法
2015/09/08 PHP
Symfony2 session用法实例分析
2016/02/04 PHP
Mootools 1.2教程 输入过滤第二部分(字符串)
2009/09/15 Javascript
跨浏览器的 mouseenter mouseleave 以及 compareDocumentPosition的使用说明
2010/05/04 Javascript
让你的CSS像Jquery一样做筛选的实现方法
2011/07/10 Javascript
javascript计算星座属相(十二生肖属相)示例代码
2014/01/09 Javascript
javascript 闭包详解
2015/07/02 Javascript
浅谈JS中的bind方法与函数柯里化
2016/08/10 Javascript
JS冒泡事件与事件捕获实例详解
2016/11/25 Javascript
JavaScript实现格式化字符串函数String.format
2016/12/16 Javascript
jQuery中Datatables增加跳转到指定页功能
2017/02/08 Javascript
对layui中表单元素的使用详解
2018/08/15 Javascript
JavaScript中判断为整数的多种方式及保留两位小数的方法
2019/09/09 Javascript
微信小程序实现搜索功能
2020/03/10 Javascript
js实现星星打分效果
2020/07/05 Javascript
Python实现二叉搜索树
2016/02/03 Python
使用pygame模块编写贪吃蛇的实例讲解
2018/02/05 Python
台湾生鲜宅配:大口市集
2017/10/14 全球购物
英国领先的瓷砖专家:Walls and Floors
2018/04/27 全球购物
腾讯公司的一个sql题
2013/01/22 面试题
CSS代码检查工具stylelint的使用方法详解
2021/03/27 HTML / CSS
计算机相关的自我评价
2014/01/15 职场文书
空气的环保标语
2014/06/12 职场文书
群众路线教育实践活动个人对照检查材料
2014/09/22 职场文书
健康状况证明模板
2014/10/23 职场文书
python如何进行基准测试
2021/04/26 Python
Jmerte 分布式压测及分布式压测配置
2022/04/30 Java/Android