什么是命名空间
命名空间是一个别系,它确保变量和函数的所有名称都是唯一的,并且不会导致任何冲突。
x = 19;print(x);x = 23;print(x);# Expected Output# 19# 23
在此示例中,将值 19 分配给变量 x。Python 将值 19 保存在内存中,然后将其地址分配给 x。以是 x 只保存一个地址,而不是一个值。如所见,可以打印该值。变动值时会发生什么情形?是否要创建新变量?不是冲突吗?内存中的旧值会发生什么?
在 Python 中,不须要像 JavaScript 中的 var、let 或 const 这样的关键字来声明变量。因此,当变动 x 当前指向的值时,会见告 Python 在内存中查看新值 23 是否已经保存在某处。它将获取地址或查找保存值 23 的位置,并获取其地址并将其分配给 x。这意味着,值 19 并没有消逝,但目前没有任何内容指向它,因此无法访问它。这也意味着,许多不同的变量可能指向相同的值。无论如何。有了这个别系,Python 可以确保在代码中没有任何重复的变量。

访问不存在的变量?发生了什么样的缺点?
print(y);# Expected Output# Traceback (most recent call last):# File "/Users/olofbaage/code-by-olof/learning-to-code/python/scope.py", # line 24, in <module># print(y);# ^# NameError: name 'y' is not defined
考试测验利用的变量在当前命名空间中不存在。
因此,命名空间和 Python 管理内存的办法确保不会对变量or 利用相同的名称。但是们可以利用已经在全局浸染域中利用的相同名称,该名称也用于函数的局部浸染域。什么是全局和局部范围。也可以在另一个模块中利用相同的名称。事实上,如果导入另一个模数,乃至可能无法掌握来自该模块的变量和函数的名称。因此,如果为了能够利用该模数而重写了所有代码,那将是致命的。
# customModule.pydef doSomeMath(x, y): return x + y;
# main.pyimport customModule def doSomeMath(x, y): return x - y;print(customModule.doSomeMath(2,3));# Expected Output: 5
在上面的示例中,您可以看如何从另一个模块访问函数。通过它, customModule.doSomeMath() 见告Python,要利用该模块中的函数,而不是文件中 main.py 的函数 customModule.py 。
但是,一下这个例子:
from customModule import adddef add(x,y): return x - y;print(add(2,3));# Expected Output: -1
在这里,没有见告 Python 在该函数的命名空间中查找该 costumModule.py 函数。由于在全局范围内有自己的 add 函数,因此 Python 利用它。如果该函数不存在,则 Python 将利用导入的函数。记住这一点非常主要!!如果覆盖导入的函数或内置函数,则永久不应这样做!! — 然后 Python 将利用该函数。另一个不好的例子:
favoritNumbers = [11,13,17,19,21,29,43,47];print(min(favoritNumbers));def min(x): sum = 0; for item in x: sum += item; return sum;print(min(favoritNumbers));# Expected Output: # 5# 200
全局和本地范围全局范围
python 文件根目录中的每个变量和函数都在全局范围内。
x = 19;y = 23;def add(): return x + y;print(add());# Expected Output: 42
变量和函数都在全局范围内。
每个函数以及函数中的嵌套函数都可以访问全局范围内的变量。
本地范围每个函数都有自己确当地浸染域。正如刚才所看到的,从这个范围中,它可以从全局范围访问变量和函数。但反过来就行不通了。
x = 19;def add(): y = 11; return x + y;print(add());print(y);# Expected Output:# 30# Traceback (most recent call last):# File "/Users/olofbaage/code-by-olof/learning-to-code/python/scope.py", line 7, in <module># print(y);# ^# NameError: name 'y' is not defined
又是:NameError。由于无法访问(查看)函数的局部范围内的变量,因此 Python 不存在该变量。结果,得到一个 NameError。
封闭如果有嵌套函数,并且这些函数依赖于变量,那么 Python 首先在函数的全局浸染域中查看须要该变量,然后它上升到下一个函数的局部浸染域,直到它到达全局浸染域。
x = 19;def doSomeMath(): y = 11; def add(a): return a + y; return add(x);print(doSomeMath());# Expected Output: 30
在该示例中,该函数 add 接管一个参数。它还利用变量 y .调用该函数并将变量通报 x 给它。
Python 首先在 的 add 范围内查找变量 y 。既然它不在那里,它就会上升一层,在那里它可以找到它。这个变量 x 乃至更高。但 add 可以访问环球范围并从那里获取它。
全局和非本地声明还有末了一件事要谈:利用语句 global 和 nonlocal 修正全局或局部范围的变量。
x = 19;def doSomeMath(): y = 11; global x; x = 43; def add(a): nonlocal y; y = 29; return a + y; return add(x);print(doSomeMath());print(x);# Expected Output: # 72# 43
全局:
利用 global 语句,可以从函数内部修正全局变量的值。为此,须要两行代码。在第一行中,见告 Python 许可我们访问全局变量 x。在第二行中,分配一个新值。
非本地:
这与局部浸染域中的变量完备相同。唯一的差异是,在这里须要非本地语句。
小心这些操作,由于它们是永久性的。如上例所示:实行函数后,x 的值仍会变动。