返回顶部
首页 > 资讯 > 后端开发 > Python >Python中的作用域与名字空间实例分析
  • 306
分享到

Python中的作用域与名字空间实例分析

2023-07-05 07:07:25 306人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

这篇文章主要介绍“python中的作用域与名字空间实例分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Python中的作用域与名字空间实例分析”文章能帮助大家解决问题。变量只是一个符号从解释器的角

这篇文章主要介绍“python中的作用域与名字空间实例分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Python中的作用域与名字空间实例分析”文章能帮助大家解决问题。

变量只是一个符号

从解释器的角度来看,变量只是一个泛型指针 PyObject *;而从 Python 的角度来看,变量只是一个用来和对象进行绑定的名字、或者说符号。

变量的定义本质上就是建立名字和对象之间的约束关系,所以 a = 1 这个赋值语句本质上就是将 a  1 绑定起来,让我们通过 a 这个符号可以找到对应的 PyLonGobject。

除了变量赋值,创建函数、类也相当于定义变量,或者说完成名字和对象之间的绑定。

def foo(): passclass A(): pass

创建一个函数也相当于定义一个变量,会先根据函数体创建一个函数对象,然后将符号 foo 和函数对象绑定起来。所以函数名和函数体之间是分离的,同理类也是如此。

import os

导入一个模块,也是在定义一个变量。import os 相当于将名字 os 和模块对象绑定起来,通过 os 可以找到指定的模块对象。

再比如 import numpy as np 当中的 as 语句同样是在定义变量,将名字 np 和对应的模块对象绑定起来,以后就可以通过 np 这个名字去获取指定的模块了。

另外,当我们导入一个模块的时候,解释器是这么做的,比如 import os

它等价于 os = __import__("os"),可以看到本质上还是一个变量赋值语句。

变量的可见性

我们知道赋值语句、函数定义、类定义、模块导入,本质上只是完成了名字和对象之间的绑定。而从概念上讲,我们实际上就是得到了一个 name 和 obj 之间的映射关系,通过 name 可以获取对应的 obj,而它们的容身之所就是名字空间。

那么要实现名字空间,应该选择哪一种数据结构呢?毫无疑问,肯定是字典。而在前面介绍字典的时候,我们说字典是被高度优化的,原因就是虚拟机本身也在大量使用字典,从这里的名字空间即可得到体现。

但是一个模块内部,名字(变量)还存在可见性的问题,比如:

number = 123Def foo():    number = 456    print(number)foo()print(number)  """456123"""

我们看到同一个变量名,打印的确是不同的值,说明指向了不同的对象,换句话说这两个变量是在不同的名字空间中被创建的。

因为名字空间是一个字典,如果两者是在同一个名字空间,那么由于字典的 key 的不重复性,当执行 number = 456 的时候,会把字典里面 key 为 "number" 的 value 给更新成 456。但外面还是打印 123,这说明两者所在的不是同一个名字空间,打印的也就自然不是同一个 number。

因此对于一个模块而言,内部是可能存在多个名字空间的,每一个名字空间都与一个作用域相对应。作用域可以理解为一段程序的正文区域,在这个区域里面定义的变量是有意义的,然而一旦出了这个区域,就无效了。

对于作用域这个概念,至关重要的是要记住:它仅仅是由程序的文本所决定的。在 Python 中,一个变量在某个位置是否起作用,是由它的文本位置决定的。

因此 Python 具有静态词法作用域,而名字空间则是作用域的动态体现,一个由程序文本定义的作用域在 Python 运行时会转化为一个名字空间(字典)。比如进入一个函数,显然进入了一个新的作用域,因此函数在执行时,会创建一个名字空间。

Python 在对源代码进行编译的时候,对于代码中的每一个 block,都会创建一个PyCodeObject 与之对应。而当进入一个新的名字空间、或者说作用域时,我们就算是进入一个新的 block 了。

而根据我们使用 Python 的经验,显然函数、类都是一个新的 block,当 Python 运行的时候会为它们创建各自的名字空间。

所以名字空间是名字(变量)的上下文环境,名字的含义取决于名字空间。更具体的说,一个变量绑定的对象是不确定的,需要由名字空间来决定。

位于同一个作用域的代码可以直接访问作用域中出现的名字,即所谓的直接访问;但不同作用域,则需要通过访问修饰符 . 进行属性访问。

class A:    a = 1class B:    b = 2    print(A.a)  # 1    print(b)  # 2

如果想在 B 里面访问 A 里面的内容,要通过A.属性的方式,表示通过 A 来获取 A 里面的属性。但是访问 B 的内容就不需要了,因为都是在同一个作用域,所以直接访问即可。

访问名字这样的行为被称为名字引用,名字引用的规则决定了 Python 程序的行为。

number = 123def foo():    number = 456    print(number)foo()print(number)

还是上面的代码,如果把函数里面的赋值语句给删掉,那么再执行程序会有什么后果呢?从 Python 层面来看,由于函数的作用域里面没有 number 这个变量,显然会寻找外部的 number。因此我们可以得到如下结论:

  • 作用域是层层嵌套的;

  • 内层作用域可以访问外层作用域;

  • 外层作用域无法访问内层作用域,尽管我们没有试,但是想都不用想。如果是把外层的 number = 123 给去掉,那么最后面的 print(number) 铁定报错;

  • 查找元素会依次从当前作用域向外查找,也就是查找元素时,对应的作用域是按照从小往大、从里往外的方向前进的;

LGB 规则

我们说函数、类有自己的作用域,但是模块对应的源文件本身也有相应的作用域。比如:

name = "古明地觉"age = 16def foo():    return 123class A:    pass

由于文件本身也有自己的作用域,显然是 global 作用域,所以解释器在运行这个文件的时候,也会为其创建一个名字空间,而这个名字空间就是 global 名字空间。它里面的变量是全局的,或者说是模块级别的,在当前文件的任意位置都可以直接访问。

而函数也有作用域,这个作用域称为 local 作用域,对应 local 名字空间;同时 Python 自身还定义了一个最顶层的作用域,也就是 builtin 作用域,像内置函数、内建对象都在 builtin 里面。

这三个作用域在Python2.2之前就存在了,所以那时候Python的作用域规则被称之为LGB规则:名字引用动作沿着local作用域(local名字空间)、global作用域(global名字空间)、builtin作用域(builtin名字空间)来查找对应的变量。

而获取名字空间,Python也提供了相应的内置函数:

  • locals 函数:获取当前作用域的 local 名字空间,local 名字空间也称为局部名字空间;

  • globals 函数:获取当前作用域的 global 名字空间,global 名字空间也称为全局名字空间;

  • __builtins__函数:或者 import builtins,获取当前作用域的 builtin 名字空间,builtint 名字空间也称为内置名字空间;

每个函数都有自己 local 名字空间,因为不同的函数对应不同的作用域,但是 global 名字空间则是全局唯一。

name = "古明地觉"def foo():    passprint("name" in globals())print("foo" in globals())"""TrueTrue"""

但是注意,我们说 foo 也是一个独立的 block,因此它会对应一个 PyCodeObject。但是在解释到 def foo 的时候,会根据这个 PyCodeObject 对象创建一个 PyFunctionObject对象,然后将字符串 foo 和这个函数对象绑定起来。

当调用 foo 的时候,再根据 PyFunctionObject 对象创建 PyFrameObject 对象、然后执行,这些留在介绍函数的时候再细说。但是我们看到 foo 也是一个全局变量,全局变量都在 global 名字空间中。

总之,global名字空间全局唯一,它是程序运行时的全局变量和与之绑定的对象的容身之所,你在任何一个地方都可以访问到 global 名字空间。正如,你在任何一个地方都可以访问相应的全局变量一样。

此外,我们说名字空间是一个字典,变量和对象会以键值对的形式存在里面。那么换句话说,如果我手动地往这个 global 名字空间里面添加一个键值对,是不是也等价于定义一个全局变量呢?

globals()["name"] = "古明地觉"print(name)  # 古明地觉def f1():    def f2():        def f3():            globals()["age"] = 16        return f3    return f2f1()()()print(age)  # 16

我们看到确实如此,通过往 global 名字空间里面插入一个键值对完全等价于定义一个全局变量。并且 global 名字空间是唯一的,你在任何地方调用 globals() 得到的都是 global 名字空间,正如你在任何地方都可以访问到全局变量一样。

所以即使是在函数中向 global 名字空间中插入一个键值对,也等价于定义一个全局变量、并和对象绑定起来。

  • name="xxx" 等价于 globals["name"]="xxx";

  • print(name) 等价于 print(globals["name"]);

对于 local 名字空间来说,它也对应一个字典,显然这个字典就不是全局唯一的了,每一个局部作用域都会对应自身的 local 名字空间。

def f():    name = "古明地觉"    age = 16    return locals()def g():    name = "古明地恋"    age = 15    return locals()print(locals() == globals())  # Trueprint(f())  # {'name': '古明地觉', 'age': 16}print(g())  # {'name': '古明地恋', 'age': 15}

显然对于模块来讲,它的local名字空间和global名字空间是一样的,也就是说,模块对应的 PyFrameObject 对象里面的 f_locals 和 f_globals 指向的是同一个 PyDictObject 对象。

但是对于函数而言,局部名字空间和全局名字空间就不一样了。调用 locals 是获取自身的局部名字空间,而不同函数的 local 名字空间是不同的。但是 globals 函数的调用结果是一样的,获取的都是 global 名字空间,这也符合函数内找不到某个变量的时候会去找全局变量这一结论。

所以我们说在函数里面查找一个变量,查找不到的话会找全局变量,全局变量再没有会查找内置变量。本质上就是按照自身的 local 空间、外层的 global 空间、内置的 builtin 空间的顺序进行查找。

因此 local 空间会有很多个,因为每一个函数或者类都有自己的局部作用域,这个局部作用域就可以称之为该函数的 local 空间;但是 global 空间则全局唯一,因为该字典存储的是全局变量。无论你在什么地方,通过调用 globals 函数拿到的永远是全局名字空间,向该空间中添加键值对,等价于创建全局变量。

对于 builtin 名字空间,它也是一个字典。当 local 空间、global 空间都没有的时候,会去 builtin 空间查找。那么 builtin 名字空间如何获取呢?答案是使用 builtins 模块,通过 builtins.__dict__ 即可拿到 builtin 名字空间。

# 等价于__builtins__import builtins#我们调用 list 显然是从内置作用域、也就是 builtin 名字空间中查找的#但我们只写 list 也是可以的#因为 local 空间、global 空间没有的话,最终会从 builtin 空间中查找#但如果是 builtins.list,那么就不兜圈子了#表示: "builtin 空间,就从你这获取了"print(builtins.list is list)  # Truebuiltins.dict = 123#将 builtin 空间的 dict 改成 123#那么此时获取的 dict 就是123#因为是从内置作用域中获取的print(dict + 456)  # 579str = 123#如果是 str = 123,等价于创建全局变量 str = 123#显然影响的是 global 空间print(str)  # 123# 但是此时不影响 builtin 空间print(builtins.str)  # <class 'str'>

这里提一下Python2当中,while 1比while True要快,为什么?

因为 True 在 Python2 中不是关键字,所以它是可以作为变量名的。那么 Python 在执行的时候就要先看 local 空间和 global 空间里有没有 True 这个变量,有的话使用我们定义的,没有的话再使用内置的 True。

而 1 是一个常量,直接加载就可以,所以 while True 多了符号查找这一过程。但是在 python3 中两者就等价了,因为 True 在 Python3 中是一个关键字,也会直接作为一个常量来加载。

局部变量是静态存储的

我们往 global 空间添加一个键值对相当于定义一个全局变量,那么如果往函数的 local 空间里面添加一个键值对,是不是也等价于创建了一个局部变量呢?

def func():    locals()["where"] = "地灵殿"    try:        print(where)    except Exception as e:        print(e)func()  # name 'where' is not defined

对于全局变量来讲,变量的创建是通过向字典添加键值对的方式实现的。因为全局变量会一直在变,需要使用字典来动态维护。

但对于函数来讲,内部的变量是通过静态方式存储和访问的,因为局部作用域中存在哪些变量在编译的时候就已经确定了,我们通过 PyCodeObject 的 co_varnames 即可获取内部都有哪些变量。

所以,虽然我们说遍历查找是按照 LGB 的方式,但是访问函数内部的变量其实是静态访问的,不过完全可以按照 LGB 的方式理解。关于这方面的细节,后续还会细说。

因此名字空间是 Python 的灵魂,它规定了 Python 变量的作用域,使得 Python 对变量的查找变得非常清晰。

LEGB 规则

前面说的 LGB 是针对 Python2.2 之前的,而从 Python2.2 开始,由于引入了嵌套函数,所以最好的方式应该是内层函数找不到某个变量时先去外层函数找,而不是直接就跑到 global 空间里面找。那么此时的规则就是LEGB:

a = 1def foo():    a = 2    def bar():        print(a)    return barf = foo()f()"""2"""

调用 f,实际上调用的是函数 bar,最终输出的结果是 2。如果按照 LGB 的规则来查找的话,由于函数 bar 的作用域没有 a,那么应该到全局里面找,打印的结果是 1 才对。

但我们之前说了,作用域仅仅是由文本决定的,函数 bar 位于函数 foo 之内,所以函数 bar 定义的作用域内嵌于函数 foo 的作用域之内。换句话说,函数 foo 的作用域是函数 bar 的直接外围作用域。

所以应该先从 foo 的作用域里面找,如果没有那么再去全局里面找。而作用域和名字空间是对应的,名字空间是作用域的动态体现,所以最终打印了 2。

另外在执行 f = foo() 的时候,会执行函数 foo 中的 def bar(): 语句,这个时候解释器会将 a=2 与函数 bar 捆绑在一起,然后返回,这个捆绑起来的整体就叫做闭包。

所以:闭包 = 内层函数 + 引用的外层作用域的变量

这里显示的规则就是 LEGB,其中 E 表示 enclosing,代表直接外围作用域。

global 表达式

有一个很奇怪的问题,最开始学习 Python 的时候,估计很多人都为此感到困惑,下面来看一下。

a = 1def foo():    print(a)foo()"""1"""

首先这段代码打印 1,这显然是没有问题的,不过下面问题来了。

a = 1def foo():    print(a)    a = 2foo()"""UnboundLocalError: local variable 'a' referenced before assignment"""

仅仅是在 print 语句后面新建了一个变量 a,结果就报错了,提示局部变量 a 在赋值之前就被引用了,这是怎么一回事,相信肯定有人为此困惑。而想弄明白这个错误的原因,需要深刻理解两点:

一个赋值语句所定义的变量,在这个赋值语句所在的整个作用域内都是可见的;

函数中的变量是静态存储、静态访问的, 内部有哪些变量在编译的时候就已经确定;

在编译的时候,因为存在 a = 2 这条语句,所以知道函数中存在一个局部变量 a,那么查找的时候就会在当前作用域中查找。但是还没来得及赋值,就 print(a) 了,所以报错:局部变量a在赋值之前就被引用了。但如果没有 a = 2 这条语句则不会报错,因为知道局部作用域中不存在 a 这个变量,所以会找全局变量 a,从而打印 1。

更有趣的东西隐藏在字节码当中,我们可以通过反汇编来查看一下:

import disa = 1def g():    print(a)    dis.dis(g)"""  7           0 LOAD_GLOBAL              0 (print)              2 LOAD_GLOBAL              1 (a)              4 CALL_FUNCTION            1              6 POP_TOP              8 LOAD_CONST               0 (None)             10 RETURN_VALUE"""def f():    print(a)    a = 2dis.dis(f)""" 12           0 LOAD_GLOBAL              0 (print)              2 LOAD_FAST                0 (a)              4 CALL_FUNCTION            1              6 POP_TOP 13           8 LOAD_CONST               1 (2)             10 STORE_FAST               0 (a)             12 LOAD_CONST               0 (None)             14 RETURN_VALUE"""

中间的序号代表字节码的偏移量,我们看第二条,g 的字节码是 LOAD_GLOBAL,意思是在 global 名字空间中查找;而 f 的字节码是LOAD_FAST,表示静态查找。因此结果说明 Python 采用了静态作用域策略,在编译的时候就已经知道了名字藏身于何处。

而且上面的例子也表明,一旦函数内有了对某个名字的赋值操作,这个名字就会在作用域内可见,就会出现在 local 名字空间中。换句话说,会遮蔽外层作用域中相同的名字。

当然 Python 也为我们精心准备了 global 关键字,让我们在函数内部修改全局变量。比如函数内部出现了 global a,就表示我后面的 a 是全局的,直接到 global 名字空间里面去找,不要在 local 空间里面找了。

a = 1def bar():    def foo():        global a        a = 2    return foobar()()print(a)  # 2# 当然,也可以通过 globals 函数拿到名字空间# 然后直接修改里面的键值对

但如果外层函数里面也出现了变量 a,而我们想修改的也是外层函数的 a、不是全局的 a,这时该怎么办呢?Python 同样为我们准备了关键字 nonlocal,但是使用 nonlocal 的时候,必须是在内层函数里面。

a = 1def bar():    a = 2    def foo():        nonlocal a        a = "xxx"    return foobar()()print(a)  # 1# 外界依旧是 1,但是 bar 里面的 a 已经被修改了

属性空间

我们知道,自定义的类里面如果没有 __slots__,那么这个类的实例对象都会有一个属性字典。

class Girl:    def __init__(self):        self.name = "古明地觉"        self.age = 16g = Girl()print(g.__dict__)  # {'name': '古明地觉', 'age': 16}# 对于查找属性而言, 也是去属性字典中查找print(g.name, g.__dict__["name"])  # 古明地觉 古明地觉# 同理设置属性, 也是更改对应的属性字典g.__dict__["gender"] = "female"print(g.gender)  # female

当然模块也有属性字典,本质上和普通的类的实例对象是一致的。

import builtinsprint(builtins.str)  # <class 'str'>print(builtins.__dict__["str"])  # <class 'str'># 另外,有一个内置的变量 __builtins__,和导入的 builtins 等价print(__builtins__ is builtins)  # True

另外这个 __builtins__ 位于 global 名字空间里面,然后获取 global 名字空间的 globals 又是一个内置函数,于是一个神奇的事情就出现了。

print(globals()["__builtins__"].globals()["__builtins__"].      globals()["__builtins__"].globals()["__builtins__"].      globals()["__builtins__"].globals()["__builtins__"]      )  # <module 'builtins' (built-in)>print(globals()["__builtins__"].globals()["__builtins__"].      globals()["__builtins__"].globals()["__builtins__"].      globals()["__builtins__"].globals()["__builtins__"].list("abc")      )  # ['a', 'b', 'c']

所以 global 名字空间和 builtin 名字空间,都保存了指向彼此的指针,不管套娃多少次,都是可以的。

关于“Python中的作用域与名字空间实例分析”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网Python频道,小编每天都会为大家更新不同的知识点。

--结束END--

本文标题: Python中的作用域与名字空间实例分析

本文链接: https://lsjlt.com/news/350244.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Python中的作用域与名字空间实例分析
    这篇文章主要介绍“Python中的作用域与名字空间实例分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Python中的作用域与名字空间实例分析”文章能帮助大家解决问题。变量只是一个符号从解释器的角...
    99+
    2023-07-05
  • Python名称空间与作用域实例分析
    本篇内容主要讲解“Python名称空间与作用域实例分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Python名称空间与作用域实例分析”吧!一 名称空间名称空间即存放名字与对象映射/绑定关系的...
    99+
    2023-06-30
  • 解密Python中的作用域与名字空间
    目录楔子变量只是一个符号变量的可见性LGB 规则局部变量是静态存储的LEGB 规则global 表达式属性空间小结楔子 前面我们介绍了栈帧,在里面看到了 3 个独立的名字空间:f_l...
    99+
    2023-02-28
    Python作用域 名字空间 Python作用域 Python 名字空间
  • Python名称空间与作用域
    目录一 名称空间1.1 内建名称空间1.2 全局名称空间1.3 局部名称空间二 作用域2.1 全局作用域与局部作用域2.2 作用域与名字查找的优先级一 名称空间 名称空间即存放名字与...
    99+
    2024-04-02
  • Python学习之名字,作用域,名字空间
    目录变量只是一个名字作用域和名字空间LGB规则eval和exec前言: 我们在PyFrameObject里面看到了3个独立的名字空间:f_locals、f_globals、f_bui...
    99+
    2024-04-02
  • Python学习之名字,作用域,名字空间(下)
    目录LEGB规则global表达式属性引用与名字引用属性空间小结前言: 这里再回顾一下函数的local空间,首先我们往global空间添加一个键值对相当于定义一个全局变量,那么如果往...
    99+
    2024-04-02
  • 名称空间与作用域
    目录 名称空间(掌握) 内置名称空间 全局名称空间 局部名称空间 加载顺序 查找顺序 ...
    99+
    2023-01-31
    作用 名称 空间
  • python名称空间与作用域详情
    目录一、名称空间1.1 内置名称空间1.2 全局名称空间1.3 局部名称空间1.4 加载顺序1.5 查找顺序二、作用域2.1 全局作用域2.2 局部作用域2.4 函数对象+作用域应用...
    99+
    2024-04-02
  • VB.NET名字空间的示例分析
    小编给大家分享一下VB.NET名字空间的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!VB.NET名字空间在编写.NET软件时,我们会用到类和其他类型。为...
    99+
    2023-06-17
  • Python作用域与名字空间源码学习笔记
    目录作用域与名字空间1. 名字绑定1.1 赋值1.2 模块导入1.3 函数、类定义1.4 as关键字2. 作用域2.1 静态作用域2.2 划分作用域2.3 闭包作用域2.4 类作用域...
    99+
    2024-04-02
  • C++中的命名空间实例分析
    这篇“C++中的命名空间实例分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C++中的命名空间实例分析”文章吧。命名空间的...
    99+
    2023-06-29
  • 解读Python编程中的命名空间与作用域
    变量是拥有匹配对象的名字(标识符)。命名空间是一个包含了变量名称们(键)和它们各自相应的对象们(值)的字典。 一个Python表达式可以访问局部命名空间和全局命名空间里的变量。如果一个局部变量和一个全局变量...
    99+
    2022-06-04
    作用 空间 Python
  • Python 作用域和命名空间
    在介绍类之前,我首先要告诉你一些Python的作用域规则。类定义对命名空间有一些巧妙的技巧,你需要知道作用域和命名空间如何工作才能完全理解正在发生的事情。顺便说一下,关于这个主题的知识对任何高级Python程序员都很有用。 让我们从一些定...
    99+
    2023-01-31
    作用 空间 Python
  • Python中的命名空间、作用域以及lo
          最近一直看一本python经典教材——《Python学习手册》,因为之前都是突击学的,也没有仔细看一些经典教材,所以感觉自己的基础掌握的还不是很好,虽然网络上资源多,但我觉得还是有必要买本教材来认真的读一读,底层基础决定上层建筑...
    99+
    2023-01-31
    作用 空间 Python
  • Python中变量的作用域实例分析
    这篇“Python中变量的作用域实例分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Python中变量的作用域实例分析”文...
    99+
    2023-06-29
  • Python函数命名空间和作用域(Local与Global)
    目录1.Local作用域2.Enclosing function locals作用域3.Global全局变量4.非局部变量nonlocal5.就近原则6.函数执行顺序7.循环、判断代...
    99+
    2024-04-02
  • C++中名称空间的示例分析
    小编给大家分享一下C++中名称空间的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!1.名称空间在C++当中,名称可以是变量、函数、结构体、枚举、类以及结构体和类的成员。这本身并没有问题,但随着项目的增大,名称之间相...
    99+
    2023-06-22
  • Python函数命名空间,作用域LEGB及Global详析
    目录一、命名空间和作用域1.1 定义1.2 内建命名空间和内建作用域1.3 全局命名空间和全局作用域1.3 局部命名空间和局部作用域1.4 总结1.5 扩展LEGB二、Global关...
    99+
    2024-04-02
  • Python命名空间与作用域深入全面详解
    目录1.命名空间2.作用域全局变量和局部变量global 和 nonlocal关键字1.命名空间 先看看官方文档的一段话: 命名空间(Namespace)是从名称到对象的映射,大部...
    99+
    2022-11-13
    Python作用域 Python命名空间
  • Python名称空间及作用域怎么用
    今天小编给大家分享一下Python名称空间及作用域怎么用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。名称空间什么是名称空间...
    99+
    2023-06-26
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作