命名空间

python中的namespace (命名空间)是映射到对象的名称。

命名空间的几个常见示例: abs() 函数、内置异常等的内置函数集合;模块中的全局名称;函数调用中的局部名称。对象的属性集合也算是一种命名空间。关于命名空间的一个重要知识点是,不同命名空间中的名称之间绝对没有关系;例如,两个不同的模块都可以定义 maximize 函数,且不会造成混淆。用户使用函数时必须要在函数名前面附加上模块名。

点号之后的名称是属性。例如,表达式 z.real 中,real 是对象 z 的属性。严格来说,对模块中名称的引用是属性引用:表达式 modname.funcname 中,modname 是模块对象,funcname 是模块的属性。模块属性和模块中定义的全局名称之间存在直接的映射:它们共享相同的命名空间。

命名空间是在不同时刻创建的,且拥有不同的生命周期。内置名称的命名空间是在 Python 解释器启动时创建的,永远不会被删除。模块的全局命名空间在读取模块定义时创建;通常,模块的命名空间也会持续到解释器退出。

函数的本地命名空间在调用该函数时创建,并在函数返回或抛出不在函数内部处理的错误时被删除。 (实际上,用“遗忘”来描述实际发生的情况会更好一些。) 当然,每次递归调用都会有自己的本地命名空间)

作用域

作用域是命名空间可直接访问的 Python 程序的文本区域。 “可直接访问” 的意思是,对名称的非限定引用会在命名空间中查找名称。

python的作用域有以下几种:

作用域虽然是静态确定的,但会被动态使用。执行期间的任何时刻,都会有 3 或 4 个命名空间可被直接访问的嵌套作用域:

  • 最内层作用域,包含局部名称,并首先在其中进行搜索

  • 封闭函数的作用域,包含非局部名称和非全局名称,从最近的封闭作用域开始搜索

  • 倒数第二个作用域,包含当前模块的全局名称

  • 最外层的作用域,包含内置名称的命名空间,最后搜索

如果把名称声明为全局变量,则所有引用和赋值将直接指向包含该模块的全局名称的中间作用域。重新绑定在最内层作用域以外找到的变量,使用 nonlocal 语句把该变量声明为非局部变量。未声明为非局部变量的变量是只读的,(写入只读变量会在最内层作用域中创建一个新的局部变量,而同名的外部变量保持不变。)

通常,当前局部作用域将(按字面文本)引用当前函数的局部名称。在函数之外,局部作用域引用与全局作用域一致的命名空间:模块的命名空间。 类定义在局部命名空间内再放置另一个命名空间。

Python 有一个特殊规定。**如果不存在生效的 global 或 nonlocal 语句,则对名称的赋值总是会进入最内层作用域。**赋值不会复制数据,只是将名称绑定到对象。删除也是如此:语句 del x 从局部作用域引用的命名空间中移除对 x 的绑定。所有引入新名称的操作都是使用局部作用域:尤其是 import 语句和函数定义会在局部作用域中绑定模块或函数名称。

global 语句用于表明特定变量在全局作用域里,并应在全局作用域中重新绑定nonlocal 语句表明特定变量在外层作用域中,并应在外层作用域中重新绑定。

下例演示了如何引用不同作用域和名称空间,以及 global 和 nonlocal 对变量绑定的影响:

def scope_test():def do_local():spam = "local spam"def do_nonlocal():nonlocal spamspam = "nonlocal spam"def do_global():global spamspam = "global spam"spam = "test spam"do_local()print("After local assignment:", spam)do_nonlocal()print("After nonlocal assignment:", spam)do_global()print("After global assignment:", spam)scope_test()
print("In global scope:", spam)

结果输出如下:

After local assignment: test spam
After nonlocal assignment: nonlocal spam
After global assignment: nonlocal spam
In global scope: global spam

注意,局部 赋值(这是默认状态)不会改变 scope_test 对 spam 的绑定。 nonlocal 赋值会改变 scope_test 对 spam 的绑定,而 global 赋值会改变模块层级的绑定。而且,global 赋值前没有 spam 的绑定。

参考官方文档:https://docs.python.org/zh-cn/3/tutorial/classes.html#python-scopes-and-namespaces

上面的内容有些晦涩难懂,其实理解下来就是,python中的命名空间可以映射到python中定义的对象,而作用域是某个命名空间对应的可直接访问的Python 程序的文本区域。对于某个命名空间,它一般对应一个作用域,在这个作用域中可以直接访问包含的对象。

一段python程序执行期间都有 3 或 4 个命名空间及可被直接访问的嵌套作用域:
比如对于上述的那个例子中,包含全局作用域、scope_test对应的作用域、do_local对应的作用域,对于do_local在其内层绑定spam,do_nonlocal由于其内部指定了nonlocal ,表明特定变量在外层作用域中,故在绑定spam时会去上一层作用域寻找并绑定,而do_global由于其内部指定了global,表明特定变量在全局作用域里,会在全局作用域中绑定,此时全局作用域中并包含该对象,此时会在全局作用域中创建该对象,并绑定。

4种作用域

L (Local) 局部作用域
E (Enclosing) 闭包函数外的函数中
G (Global) 全局作用域
B (Built-in) 内建作用域 以 L –> E –> G –>B 的规则查找,即:在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内建中找。

根据 Python 访问局部变量和全局变量的规则:当搜索一个变量的时候,Python 先从局部作用域开始搜索,如果在局部作用域没有找到那个变量,那样 Python 就会像上面的介绍的作用域范围逐层寻找,如果找不到则抛出 UnboundLocalError 异常。

虽然在内部能够找到外部的变量,但是未声明为非局部变量的变量是只读的,(写入只读变量会在最内层作用域中创建一个新的局部变量,而同名的外部变量保持不变。),所以此时nonlocal以及global关键字的用处来了,只有声明某个变量在全局作用域或者外层作用域,才能够对这个变量进行修改。

参考:
https://zhuanlan.zhihu.com/p/111284408
https://docs.python.org/zh-cn/3/tutorial/classes.html#python-scopes-and-namespaces

python的作用域问题相关推荐

  1. Python变量作用域问题

    本文最后更新于2018-6-20,可能会因为没有更新而失效.如已失效或需要修正,请联系我! 今天在用Python写程序时突然想起了Python变量作用域的问题,代码如下: def run():glob ...

  2. Python 变量作用域

    变量作用域(scope)在Python中是一个容易掉坑的地方. Python的作用域一共有4中,分别是: L (Local) 局部作用域 E (Enclosing) 闭包函数外的函数中 G (Glob ...

  3. python作用域的理解-理解Python的UnboundLocalError(Python的作用域)

    今天写代码碰到一个百思不得解为什么会出错的代码,简化如下: 1 2 3 4 5 6 7 x=10 deffunc(): ifsomething_true(): x=20 print(x) func() ...

  4. python作用域顺序排列_详解Python函数作用域的LEGB顺序

    本文为大家介绍了Python函数作用域的查找顺序,供大家参考,具体内容如下 1.什么是LEGB? L:local 函数内部作用域 E:enclosing 函数内部与内嵌函数之间 G:global 全局 ...

  5. python的作用域分别有几种_python 作用域知识点整理

    1.块级作用域 想想此时运行下面的程序会有输出吗?执行会成功吗? 1 2 3 4 5 6 7 8 9 10 11 12 #块级作用域 if 1 == 1: name= "lzl" ...

  6. [python]变量作用域问题

    先列出参考链接: python变量作用域–作者:lovingprince python开发杂货铺:作用域的痛点-作者:Assassin python中在哪些情况下必须使用global来声明全局变量 p ...

  7. Python 变量作用域问题 函数名.变量名

    刚接触Python,主要想利用它做数据处理.我用的是Python2.7.5,win7系统 最近在看<机器学习实战>,第三章决策树中有一段代码,摘抄如下,对于用颜色标注部分,刚开始没看懂什么 ...

  8. Python 变量作用域与函数(4)

    Python 的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC语言的一种继承.Py ...

  9. 【python教程入门学习】Python变量作用域(通俗易懂)

    Python 中变量的访问权限取决于其赋值的位置,这个位置被称为变量的作用域.Python 的作用域共有四种,分别是:局部作用域(Local,简写为 L).作用于闭包函数外的函数中的作用域(Enclo ...

  10. python的作用域和优先级_Python作用域

    python作用域 LEGB原则 python中作用域有四种: L (Local) 局部作用域 E (Enclosing) 闭包函数外的函数中 G (Global) 全局作用域 B (Built-in ...

最新文章

  1. 织梦html编辑器有问题怎么办,dede 织梦编辑框显示不出来的问题
  2. 1.1 MATLAB数值数据
  3. 阿里开源分布式限流框架 -Sentinel Go 0.3.0 发布,支持熔断降级能力
  4. 210506阶段四Python基本语法
  5. 根据您的命令-命令设计模式
  6. java 年份对应的中国生肖
  7. bmp转换tiff c++代码_如何用Java语言将图像转换为PDF?Spire.PDF for Java轻松搞定
  8. boost asio异步通信
  9. 箭头函数和Buffer对象
  10. 数据分析师mysql面试题_30个sql面试题及答案(数据分析师福利)
  11. r7525服务器电源管理系统,戴尔 R7525评估:EPYC内核密度让英特尔心碎
  12. 1094: 【基础】填词 【循环】
  13. 蚂蚁金服副总裁蒋国飞:技术全面开放,与合作伙伴共发展
  14. Java 集合中遍历删除元素抛异常的原因,从ArrayList说起
  15. 双摄像头的实时视频拼接及目标跟踪(一)
  16. win10如何开启自带的虚拟机?
  17. Cir 和 IBIS模型的使用
  18. pulsar分析以及各消息队列对比
  19. 电吉他伤感独奏曲《永远之后》张俊文
  20. golang GF框架

热门文章

  1. CentOS部署Samba服务
  2. Git常规使用笔记及注意事项了解一下
  3. 如何进入服务器的数据库
  4. Android SparseArray和ArrayMap相关总结
  5. [分享]尝试赞美这残缺的世界
  6. 素材解析字体下载网!设计师必备!!!
  7. 快要失传的老北京的北京话
  8. GitHub 详细使用【 详细 】
  9. JAVA面试题(搞笑)
  10. 【MFC】一个最简单的MFC程序(9)