楔
在这里,回头看看功能的本地空间。首先,我们为全局变量添加了一个关键值,等同于定义全局变量。
对于全局变量,变量的创建是通过在字典中添加键值对来实现的。由于全局变量将始终更改,因此您需要使用字典来维护动态维护。
但是对于函数,内部变量是通过静态方式存储和访问的,因为编译时局部范围中的变量是确定的。我们可以通过PyCodeObject的Co_varnames获取内部变量。
因此,尽管我们说搜索是以LGB的形式找到的,但访问功能中的变量实际上是静态访问,但是您可以在LGB中充分理解它。对此领域的详细信息进行了重新了解,您将在该区域中谈论它。未来。
因此,空间的名称是Python的灵魂。它规定了Python变量的范围,这使得该变量非常清晰。
legb规则
前面提到的LGB针对Python2.2,从Python2.2开始,因为引入了嵌套功能,最好的方法应该是当找不到变量时找不到内层函数。全球空间。此时的规则是Legb:
实际上,调用F函数栏被调用,最终输出结果为2。如果您根据LGB规则找到它,因为功能栏的功能没有A,则应在全球情况。打印的结果是1。
但是我们之前说,范围的范围仅由文本决定。函数栏位于函数foo中,因此函数栏的函数定义嵌入到函数foo的函数字段中。换句话说,函数范围foo的范围是函数栏的直接外围范围。
因此,您应该首先从foo领域找到它。
另外,当您执行f = foo()时,您将在函数foo中执行def bar()。目前,解释器将与函数栏和返回。Clublususe将a = 2捆绑。
因此:闭合=内层函数 +外层范围
这里显示的规则是legb,其中e表示封闭,代表直接外围范围。
全球表达
有一个非常奇怪的问题。当我第一次学习python时,作者这次也感到困惑。让我们看看下面。
首先,此代码打印1,这显然没有问题,但是以下问题出现了。
在打印说明后面建立了一个新的变量A,并报告了结果。提示在分配之前引用了本地变量A。什么事?我相信某人必须对此感到困惑。如果您想了解此错误的原因,则需要了解两点:
编译时,因为a = 2的说明,如果您知道函数中有局部变量A,那么当您找到它时,您会在当前范围中找到它。但是在分配值之前,它是打印(a),因此报告了错误:分配前引用了本地变量A。但是如果没有a = 2,则不会报告错误,因为您知道本地范围中没有变量,因此,您会找到一个全局变量a要打印1
更有趣的事物隐藏在字节码中,我们可以通过计数器编译进行检查:
中间的订单号表示字节代码的偏移。让我们先看看第二个。G的字节码为load_global,这意味着在全局名称空间中找到。F字节代码为load_fast,这意味着在本地名称spaceFind中。因此,结果表明Python使用静态域策略,并且在编译时,您已经知道该名称的位置是隐藏的。
此外,上面的示例还表明,一旦将函数分配给某个名称,此名称将在函数的范围中可见,并将显示在本地名称空间中。换句话说,同一名称将在外场。
当然,python还仔细地为我们准备了全局关键字,让我们修改函数中的全局变量。例如,全局A出现在函数内部,这意味着我背后的A是全局,并直接转到全局名称找到它的空间。在当地空间中找不到它。
但是,如果变量a在外部函数中也出现,而我们要修改的内容也是一个,而不是全局A。我们现在应该做什么?在内层函数中。
属性参考和名称参考
属性引用也是名称参考,其本质是在名称空间中引用的对象。这是相对简单的。例如,a.xxx是在A中找到属性XXX。此规则不受LEGB Action域的限制,也就是说,在A中找到它,没有,否,否。
但是要注意的一件事,我们说搜索将遵循LEGB规则,但这必须仅限于其所在的模块。如果是多个模块,它将不起作用。
为了引入模块,我们将详细介绍。简而言之,您可以简单地认为您可以将A.Py的内容进行执行,因此此处是打印(名称)。
但是,在执行b.py时,未定义变量名称。如果可以指向A,则相当于打印(名称),我们还定义了上面的名称变量。
显然,即使我们导入了A.Py中的内容仍在模块中。我们还说,尽管名称参考是LegB规则,但它无法跨越该模块的位置。print(name)是在a.py中,可变名称在b.py中定义,因此不可能加速模块a的名称以访问名称b。
因此,我们发现,尽管每个模块的内部动作范围的规则有点复杂,因为它们必须遵循LEGB。但是,模块和模块的范围非常清楚,这是彼此独立的。
对于模块,我们将来将详细讨论它。简而言之,通过方式,从本质上讲,在指定的名称空间中找到相应的属性。
属性空间
我们知道,如果自定义类中没有__slots___,则该类的实例对象将具有属性字典。
当然,该模块还具有属性词典,该字典与类的实例对象基本相同。
此外,这个__ builtins__位于全球名称空间中,然后获得全球名称空间的Globals是另一个构建的功能,因此出现了一个神奇的事情。
因此,Global的名称空间和内置的名称空间彼此保留了指针。无论娃娃设置了多少次,都可以。
概括
在Python中,名称的可见范围(变量)由动作范围确定,范围的范围由语法静态划分,并且分区规则的完善如下:
与示波器相对应的是,Python使用Dynamic名称空间中的名称空间和PydictObject对象的名称保留PydictObject对象的名称。有4个这样的名称空间:有4个:有4个:
在寻找名称时,您会根据LEGB规则找到它,但请注意,它不能按照文件本身(即根据其自己的文件)跨越文件本身。如果属性搜索找到内置空间,它证明这是最后一个固执的。如果找不到内置空间,那么您只能报告一个错误,并且不可能转到其他文档来查找它。
以上是该共享的所有内容。如果您想了解更多信息,请转到公共帐户:Python编程学习圈,每日干货共享