当前位置: 首页 > 网络应用技术

Python的名称,范围,名称空间

时间:2023-03-07 11:26:57 网络应用技术

  楔

  我们在pyframeObject中看到了3个独立的名称空间:f_locals,f_globals,f_builtins。名称空间对于Python来说是一个非常重要的概念。Python虚拟机的操作机制和名称空间具有非常紧密的连接。在Python中,名称和范围的概念也与名称空间的概念紧密相关。让我们分析下面如何反映这些概念。

  变量只是一个名称

  我们很早就说过,从解释器的角度来看,变量只是一个通用的指针pyobject *,从python的角度来看,变量只是一个名称或符号,用于与对象绑定以绑定对象的对象。

  变量的定义本质上是名称和对象之间的约束,因此分配语句A = 1基本上是绑定A和1。让我们通过A符号找到相应的Pylongobject。

  除了变量分配外,创建功能和类也等于定义变量或名称和对象之间的绑定。

  创建函数也等同于定义变量。它将首先根据功能主体创建一个函数对象,然后绑定名称foo和函数对象。因此,函数名称和功能主体是分开的,以及同一类。

  导入模块也定义了变量。ImportOS等同于绑定名称OS和模块对象。通过OS,您可以找到指定的模块对象。

  导入numpy AS NP中的AS语句也定义了变量,绑定名称NP和相应的模块对象,然后您可以通过NP名称获得指定的模块。

  此外,当我们导入模块时,将完成解释器。例如:导入OS等同于OS = __导入__(“ OS”),可以看出它本质上是一个分配语句。

  活动域和名称空间

  我们说分配语句,功能定义,类定义和模块导入本质上只是名称和对象之间的绑定。在概念的角度,我们实际上获得了名称和OBJ之间的映射关系。通过名称,我们可以得到相应的OBJ,他们的身体是名称空间。

  因此,名称空间是通过pydictObject对象实现的,该对象几乎适用于映射。当我早些时候介绍字典时,我们说字典得到了高度优化,因为虚拟机身也很大程度上依赖于词典,而名称空间也很依赖从这里可以反映。

  但是在模块内,该名称仍然可见,例如:

  当我们看到相同的变量名称时,打印确实是不同的值,表明它指向不同的对象。换句话说,这两个变量是在不同的名称空间中创建的。

  然后我们知道这个名称空间本质上是词典。如果两者在同名空间中,则因为字典的键未重复,当执行a = 2时,字典中的键已更新为a as a.main 2.main 2.但外部打印1,这表明两个不是同一名称空间,并且印刷自然不是相同的。

  因此,对于一个模块,内部可能有多个名称空间,每个名称空间对应于动作范围。范围可以理解为程序的文本区域。该区域中定义的变量是有意义的。但是,一旦该区域释放,它将无效。

  对于范围的概念,重要的是要记住,它仅由源程序的文本确定。在python中,变量是否在某个位置上起作用,是否由其文本位置确定。

  因此,Python具有静态范围(词汇范围),名称空间是范围的动态实施例。通过程序文本定义的范围将在运行Python时转换为名称空间,即PydictObject对象。输入函数显然进入新范围,因此,当执行函数时,它将创建一个名称空间。

  我们在此之前说,在编译Python源代码时,代码中的每个块会创建一个与之相对应的pycodeObject。并且在输入新名称空间或操作范围时,我们甚至输入了一个新块。

  根据我们使用Python的经验,显然功能和课程是一个新的障碍。当Python运行时,它将为他们创建自己的名称空间。

  因此,名称空间是名称的名称或变量的上下文,名称的含义取决于名称space。更具体地说,一个不确定的变量 - 缩合对象,需要由名称space确定。

  位于同一范围中的代码可以直接访问在操作范围中出现的名称,即SO称为直接访问;但是,需要通过访问装饰器来访问不同的范围。

  如果要访问b中的内容,则需要在A到A中获取属性。但是不需要访问B的内容,因为它处于相同角色的相同范围,因此您可以直接访问它。

  访问名称的行为称为名称参考,并引用该名称的规则确定Python程序的行为。

  仍然是上面的代码。如果我们在函数中删除a = 2,则意味着该函数函数域中没有变量,因此执行程序的后果是什么?从Python级别,它显然正在寻找外部A因此,我们可以得出以下结论:

  LGB规则

  我们说功能和类有自己的范围,但是与该模块相对应的源文件也具有相应的范围。例如:

  因为此文件本身也有自己的范围,所以显然是全局范围,因此当解释器运行此文件时,它也将为其创建一个名称空间,此名称空间是全局名称空间。它中的变量是全局或模块级别,可以直接在当前文件的任何位置访问。

  该功能还具有范围。该范围称为本地范围,该范围与本地名称空间相对应。同时,Python本身还定义了顶级范围,即内置范围。

  这三个范围存在于Python2.2之前,因此Python的Python范围规则称为LGB规则:沿本地名称空间),全局名称空间(全局名称空间),内置动作域(buildin inconin(buildInin)名称空间)查找相应的变量。

  对于名称空间,Python还提供了相应的构建-in函数:

  每个函数都有自己的本地名称空间,因为不同的功能对应于不同的范围,但是全局名称空间是唯一的全局。

  内部...表示输出的一部分被省略,我们看到创建的全局变量在其中。和FOO也是一个变量,指向函数对象。

  但是请注意,我们说FOO也是一个独立的块,因此它对应于PyCodeObject。但是在解释Def Foo时,它将基于此PyCodeObject对象创建一个PyFunctionObject对象,然后绑定FOO和函数对象。

  当我们调用foo时,基于pyfunctionObject对象创建一个pyframeObject对象,然后执行它,然后在剩下介绍函数时谈论它。简而言之,我们看到foo也是一个全局变量,并且全局变量是在全球名称空间中。

  简而言之,全球名称空间是唯一的。这是程序正在运行和对象绑定对象的地方。您可以访问任何地方的全局名称空间。

  此外,我们说名称空间是字典,变量和对象将以键值对的形式存在。定义全局变量?

  我们看到这是真的。通过在全局名称空间中插入一个键值,它完全等同于定义全局变量,并且全局名称空间是唯一的。您可以在任何地方获取全球名称空间,就像您可以在任何地方访问全局变量一样。

  因此,即使将其插入函数函数空间中的钥匙值对,也等同于定义全局变量并将其与对象绑定。

  对于本地名称空间,它也对应于字典。显然,这个词典不是全球唯一的词典。每个本地范围将对应于其自己的本地名称空间。

  显然,对于模块,其本地名称空间与全局名称空间相同,即pyframeObject中的f_locals和f_globals对应于模块对应于同一pydictObject对象的f_globals。

  但是对于功能,本地名称空间和全局名称空间不同。当地人是本身的本地名称空间,并且不同功能的本地名称空间是不同的。但是,Globals功能的调用结果是相同的。获得了所有的全局名称空间,这与在函数中找不到函数时找到全局变量的结论一致。

  因此,我们说在功能中找到变量。如果您找不到它,您会找到一个全局变量,并且全局变量不会在变量中找到构建。,以及内置的内置空间。

  因此,由于每个功能或类都有自己的本地范围,因此将有许多本地空间。该局部范围可以称为函数的本地空间;全局变量。无论您在哪里,您都可以通过调用Globals功能,将键值对添加到空间,并等待创建的创建,从而始终获得全局名称空间全局变量。

  它也是内置名称空间的字典。当地空间和全球空间不可用时,他们将转到内置空间。,您可以通过内置。__dict__获得内置的名称空间。

  这是一种提及Python2的方法,而1比真实的速度快,为什么?

  因为true不是Python2中的关键字,所以可以用作变量名称。到执行Python时,您必须首先查看本地空间和全局空间中是否存在真实变量。如果我们使用它,则如果不使用,请使用构建-in true。

  1是一个常数,只需直接加载它,因此虽然有更多符号可以找到此过程。但是,python3中的两个是等效的,因为true是python3中的关键字,它也将直接作为常数加载。

  评估和执行

  请记住,在介绍Eval和Exec时,我们说这两个函数还可以接收第二个参数和第三个参数,该参数代表全局名称空间和本地名称空间。

  至于评估,也是相同的:

  因此,名称空间本质上是词典。so称为变量只是字典中的一个关键。为了进一步加深印象,给出一个模块的示例:

  怎么样了,这是非常有趣的吗?以上是共享的所有内容。如果您想了解更多信息,请转到公共帐户:Python编程学习圈,每日干货共享