初学者教程之命名空间,范围解析及LEDB规则
初学者教程之命名空间,范围解析及LEDB规则。这是一篇关于采用LEGB规则实现Python变量命名空间及范围解析的简短教程。下面章节将会提供简短的可以说明问题的示例代码块来简要阐述问题。您可以简单的从头至尾阅读本教程,但我鼓励您去执行这些代码段。你可以复制粘贴这些代码段,但是为了方便您也可以下载IPython笔记。
章节
•章节
•目标
•命名空间和范围介绍
o命名空间
o范围
o提示:
o通过LEGB规则解析变量名的范围
•1.LG-本地和全局范围
o原因:
o原因:
•2.LEG–局部、封闭和全局范围
o原因:
•3.LEGB–局部、封闭、全局、内置
o原因:
•自由练习
•结论
o经验法则
o解决方案
o警告:对于循环变量“leaking”加入全局命名空间
目标
•命名空间和范围:Python是从哪里寻找变量名?
•我们可以在同一时间定义或重用多个对象的变量名吗?
•Python是通过哪种方式为变量名搜索不同的命名空间的呢?
命名空间和范围介绍
命名空间
大致来说,命名空间只是将名称映射到对象的容器。正如你可能已经听过,Python中所有的字符串、列表、函数、类等等都是对象。如此,“对象与名称”的映射关系允许我们使用已经为这个对象分配的名称来访问这个对象。例如,如果我们做一个简单的字符串分配,可以通过:a_string=“Hellostring”,我们创建了一个关于“Hellostring”的对象,从此以后我们就可以通过它的变量名a_string来访问它。
我们可以想象一个命名空间为Python字典结构,字典的键在哪里代表它的名字以及字典的值在哪里代表对象本身(这也是目前在Python中命名空间该如何实现),例如,
a_namespace={'name_a':object_1,'name_b':object_2,...}
现在,棘手有部分是在Python中我们有多个独立的命名空间,并且名称可以被不同的命名空间重复使用(只有对象是唯一的,例如,
a_namespace={'name_a':object_1,'name_b':object_2,...
b_namespace={'name_a':object_3,'name_b':object_4,...}
例如,当我们调用一个循环或定义一个函数时,它将创建自己的命名空间。命名空间也有不同的层次(所谓的“范围”),我们将在下一节中更详细地讨论。
范围
在上述章节中,我们已经了解到命名空间可以独立存在,彼此和他们的结构在一定的层次,这给我们带来了“范围”。Python中的“范围”在我们为“命名对象”映射搜索命名空间时定义了“层级”。
例如,让我们思考一下下面的这段代码:
在这里,我们仅仅只对变量名i定义了两次,一次是是在foo函数中。
•foo_namespace={'i':object_3,...}
•global_namespace={'i':object_1,'name_b':object_2,...}
所以,如果我们想要打印变量i的值,Python是如何知道应该查找哪个命名空间呢?这个地方就需要Python的LEGB规则来实现了,我们将在下个章节讨论。
提示:
如果我们想要打印出字典的全局变量和局部变量的映射,我们可以使用global()和local()函数。
通过LEGB规则解析变量名范围
我们已经看到,多个命名空间可以彼此独立存在,它们可以在不同的层次水平包含相同的变量名。“范围”定义在哪个层次,Python为其相关对象搜索了一个特定的“变量名”。现在,下一个问题是:Python是采用什么方式在它找到对象名称的映射之前搜索命名空间的不同级别呢?
答案是:Python使用LEGB规则,即
局部->封闭->全局->内置
箭头应该指向命名空间层次结构搜索顺序的方向。
•局部可以在函数内部或类方法中,例如。
•封闭可以是它的enclosing方法,例如,一个方法被包含在另一个方法中。
•全局是指执行脚本的最高级别,以及
•内置是Python自己保留的特殊名称。
所以,如果一个特定的名称:对象映射不能在本地命名空间中找到,下一步封闭范围的命名空间将会被搜索。如果在封闭范围的搜索也是不成功的,Python将会到全局命名空间去搜索,最终,它将搜索内置命名空间(附注:如果名称在任何的命名空间都找不到,系统将报告NameError)。
注:
命名空间还可以嵌套,例如如果我们导入的模块,或者如果我们定义新类。在这种情况下,我们必须使用前缀来访问这些嵌套的命名空间。让我在下面的代码块中说明这个概念:
(这也是为什么我们在通过“fromamoduleimport*”时必须注意,因为在加载变量名到全局命名空间时很可能会覆盖已经存在的变量名。)
1.LG–局部和全局范围
例1.1
作为热身练习,让我们先忘记在LEGB规则中封闭(E)和内置(B)的范围,来看一看LG----局部和全局范围。
下面的代码将打印什么呢?
原因:
我们首先调用a_func(),这应该是打印a_var值。根据LEGB规则,这个方法将会首先在局部范围(L)查看是否a_var是被定义的。因为a_func()没有定义自己a_var,它会向上一级全局范围(G)查找,直到a_var之前定义的范围。
例1.2
现在,让我们在全局和局部范围定义变量a_var.
你能猜到下面的代码将会产生什么?
原因:
当我们调用a_func()时,首先它会在局部范围(L)中查找a_var,因为a_var已经在局部范围a_func中定义,它的赋值localvarible就会被打印。注意这不会影响在不同范围的全局变量。
然后,它也在可能会修改全局的,例如,如果我们在重新赋值时使用全局关键字。下面的例子将会说明:
但是我们必须小心这个顺序:如果我们没有明确的告诉Python我们想要使用全局范围来尝试修改变量值就很容易出现UnboundLocalError错误。
Python培训、Python培训班、Python培训机构,就选光环大数据!
还不够过瘾?想学习更多?点击 http://hadoop.aura.cn/python/ 进行Python学习!
大数据培训、人工智能培训、Python培训、大数据培训机构、大数据培训班、数据分析培训、大数据可视化培训,就选光环大数据!光环大数据,聘请专业的大数据领域知名讲师,确保教学的整体质量与教学水准。讲师团及时掌握时代潮流技术,将前沿技能融入教学中,确保学生所学知识顺应时代所需。通过深入浅出、通俗易懂的教学方式,指导学生更快的掌握技能知识,成就上万个高薪就业学子。 更多问题咨询,欢迎点击------>>>>在线客服!