详解Python的作用域和命名空间
最近在学习Python,不得不说,Python真的是一门很好用的语言。但是学习的过程中关于变量作用域(scope)的命名空间(namespace)的问题真的把我给搞懵了。在查阅了相关资料之后,觉得自己对Python的作用域和命名空间有了一定得了解。故写在这里,一方面加深自己的理解,另一方面分享知识。
一、本篇博客需要解决的问题。
1、什么是作用域和命名空间?
2、Python中作用域和命名空间的工作原理是什么?
3、我怎样在Python中声明一个全局变量(global variable),局部变量(local variable)和nonlocal variable, which works between global scope and local scope?
4、如果我想让一个变量在多个Python脚本之间传递,我该怎么做?
二、解决问题
1、什么是作用域和命名空间?
命名空间是从名称到对象之间的映射。对象可以是Python脚本,函数,类等,也就是说Python中的每一个对象,都有其对应的命名空间。在不同的命名空间下声明相同名称的变量不冲突。
作用域是指Python程序运行时,一个命名空间相对应的作用范围的文本上的解释。英文原文为:A scope is a textual region of a Python program where a namespace is directly accessible. “Directly accessible” here means that an unqualified reference to a name attempts to find the name in the namespace.
2、Python中作用域和命名空间的工作原理是什么?
命名空间在不同的时间段被创建并且拥有不同的生命周期。有三种命名空间。
(1)、包含Python内置名称的命名空间。这种命名空间在Python编译器启动时被创建,在编译器关闭时销毁。
(2)、全局命名空间。即一个脚本文件(module)的命名空间。它在脚本文件被读取时创建,在编译器关闭时销毁。
(3)、局部命名空间。一般指一个函数的命名空间。在函数被调用时创建,在函数调用结束或者函数引发异常时销毁。
一个命名空间至少连接着三层相互嵌套的作用域。
(1)、the innermost scope,搜索变量时最先被搜索的作用域,包含local name
(2)、the scope of any enclosing functions,当(1)没有搜索到目标name时,就会向外扩张到一个封闭代码块或者函数的作用域,包含nonlocal name\nonglobal name
(3)、the next-to-last scope, 当(2)没有搜索到目标name时,搜索当前脚本和引用模块的name
(4)、the outermost scope,最后搜索的作用域,包含Python内置名称。
3、我怎样在Python中声明一个全局变量(global variable),局部变量(local variable)和nonlocal variable, which works between global scope and local scope?
Python中声明变量时,若前面不加关键字,这该变量默认为当前函数或代码块的局部变量
若前面加上global关键字,这意味着该变量是对一个全局变量的引用
若前面加上nonloca关键字,则意味着该变量是对中间层次作用域中的一个变量的引用
详情请看第三部分
4、如果我想让一个变量在多个Python脚本之间传递,我该怎么做?
简单。新建一个global.py脚本,把你需要用到的变量声明在里面,然后在需要用到这些变量的脚本里导入这个global.py脚本即可。
三、代码示例及相关解释
# -*- coding: utf-8 -*-
# author: zxr
# time: 2019-04-07
# functionality: test scope and namespace
# Python3.7.2 def scope_test():
def do_local():
spam = "local spam"
print (spam)
def do_nonlocal():
nonlocal spam
spam = "do_local's nonlocal spam"
do_nonlocal()
print (spam)
def do_nonlocal():
nonlocal spam
spam = "nonlocal spam"
def do_global():
global spam
spam = "global spam"
spam = "test spam"
do_local()
print ("After local assignment, spam = " + spam)
do_nonlocal()
print ("After nonlocal assignment, spam = " + spam)
do_global()
print ("After global assignment, spam = " + spam) if __name__ == '__main__':
scope_test()
print ("global spam = " + spam)
首先,调用scope_test函数的时候,scope_test.spam被声明,
然后,调用scope_test.do_local函数,scope_test.do_local.spam被声明
接着,调用scope_test.do_local.do_nonlocal函数,scope_test.do_local.spam被引用
接着,调用scope_test.do_nonlocal函数,scope_test.spam被引用
最后,调用scope_test.do_global函数,全局变量spam被声明
这段代码中,一定要仔细去理解每一个步骤,这样才能理解作用域和命名空间之间微妙的关系。
第一篇博客!
诚惶诚恐,希望有用!
若是无用,希望无害!
最后,如有不对的地方,欢迎大家批评指正!
详解Python的作用域和命名空间的更多相关文章
- 详解Python中内置的NotImplemented类型的用法
它是什么? ? 1 2 >>> type(NotImplemented) <type 'NotImplementedType'> NotImplemented 是Pyth ...
- 举例详解Python中的split()函数的使用方法
这篇文章主要介绍了举例详解Python中的split()函数的使用方法,split()函数的使用是Python学习当中的基础知识,通常用于将字符串切片并转换为列表,需要的朋友可以参考下 函数:sp ...
- 详解Python中re.sub--转载
[背景] Python中的正则表达式方面的功能,很强大. 其中就包括re.sub,实现正则的替换. 功能很强大,所以导致用法稍微有点复杂. 所以当遇到稍微复杂的用法时候,就容易犯错. 所以此处,总结一 ...
- 详解Python模块导入方法
python常被昵称为胶水语言,它能很轻松的把用其他语言制作的各种模块(尤其是C/C++)轻松联结在一起.python包含子目录中的模块方法比较简单,关键是能够在sys.path里面找到通向模块文件的 ...
- 详解python函数的参数
详解python函数的参数 一.参数的定义 1.函数的参数在哪里定义 在python中定义函数的时候,函数名后面的括号里就是用来定义参数的,如果有多个参数的话,那么参数之间直接用逗号, 隔开 案列: ...
- 详解Python函数参数定义及传参(必备参数、关键字参数、默认可省略参数、可变不定长参数、*args、**kwargs)
详解Python函数参数定义及传参(必备参数.关键字参数.默认可省略参数.可变不定长参数.*args.**kwargs) Python函数参数传参的种类 Python中函数参数定义及调用函数时传参 ...
- 详解Python 切片语法
Python的切片是特别常用的功能,主要用于对列表的元素取值.这篇文章主要介绍了详解Python 切片语法,需要的朋友可以参考下 Python的切片是特别常用的功能,主要用于对列表的元素取值.使用切片 ...
- 详解Python编程中基本的数学计算使用
详解Python编程中基本的数学计算使用 在Python中,对数的规定比较简单,基本在小学数学水平即可理解. 那么,做为零基础学习这,也就从计算小学数学题目开始吧.因为从这里开始,数学的基础知识列位肯 ...
- 详解python的装饰器decorator
装饰器本质上是一个python函数,它可以让其它函数在不需要任何代码改动的情况下增加额外的功能. 装饰器的返回值也是一个函数对象.它经常用于有切面需求的场景,比如:插入日志,性能测试,事务处理,缓存, ...
随机推荐
- Hibernate的Cascade——级联操作
在Hibernate中,针对持久化实体的配置文件中有Cascade这样一个属性,顾名思义就是级联,也就是说在操作当 前实体时,针对当前实体的操作会影响到相应配置的关联实体.比如针对当前实体进行保存操作 ...
- 设计的一些kubernetes面试题目
这几个月参与了几场面试,设计了多道面试题,觉得可以综合考察应聘人对kubernetes的掌握情况.在这里分享下,供应聘人自查以及其他面试官参考. 这些面试题的设计初衷并不是考察kubernetes的使 ...
- eclipse改jsp文件编码格式 统一设置
- P4630 [APIO2018] Duathlon 铁人两项
思路 圆方树,一个点双中的所有点都可以被经过,所以给圆点赋值-1,方点赋值为圆点个数,统计圆点两两之间的路径权值和即可 代码 #include <cstdio> #include < ...
- 优雅的使用Linux
优雅的使用Linux 系统安装 启动盘制作 通过rufus烧制官网镜像,注意根据自己系统的引导模式选择相应模式,不确定的,可以在windows中通过Win + R 快捷键调出"运行" ...
- 最大子段和的DP算法设计及其效率测试
表情包形象取自番剧<猫咪日常> 那我也整一个 曾几何时,笔者是个对算法这个概念漠不关心的人,由衷地感觉它就是一种和奥数一样华而不实的存在,即便不使用任何算法的思想我一样能写出能跑的程序 直 ...
- Python+MapReduce实现矩阵相乘
算法原理 map阶段 在map阶段,需要做的是进行数据准备.把来自矩阵A的元素aij,标识成p条<key, value>的形式,key="i,k",(其中k=1,2,. ...
- HDU - 3652
#include<stdio.h> #include<string.h> #include<math.h> #include<time.h> #incl ...
- [转]OpenStreetMap/Google/百度/Bing瓦片地图服务(TMS)
转自:https://blog.csdn.net/youngkingyj/article/details/23365849 开源与成熟商业的瓦片地图服务(TMS 2 WMTS),都有如下共同的特性 ...
- 实验九 FBG 团队项目需求改进与系统设计
任务一 A.<项目需求规格说明书>分析 根据老师的指导以及本周所学的OOA,分析改进上周编写的<项目需求规格说明书>,发现需求项目书UML图例描述不够完善,仅仅是用例图没办法更 ...