名称空间与作用域


名称空间

名称空间:(namespace)存放名字的地方,是对栈区的划分,听了一种在相同项目中避免名字冲突的方法

有了名称空间之后我们就可以在栈区存放相同的名字,详细的名称空间分为三种

1.1 内置名称空间

存放的是python解释器内置的名字 英文为 built-in

>>> print

>>> input

存活周期:python解释器启动则产生,python解释器关闭则销毁

1.2 全局名称空

只要不是函数内定义、也不是内置的、剩下的都是全局名称空间的名字,即模块中的变量,包括函数、类、其它导入模块、模块级的变量和常量 英文为 global

import os  # 模块
x = 10. # 变量名
if 13 > 3:
  y = 20  # 也属于全局名称空间
  
  
def func():  # 函数名
  a = 1
  b = 2

存活周期:该文件执行则产生,文件运行完毕之后销毁

1.3 局部名称空间

在函数内定义的名称,包括函数参数,局部定义的变量 英文为local

x = 10  # x为全局名称
def func():
  a = 20  # a是局部名称
  def func2():
    b = 30. # b是内嵌的局部名称

存活周期:调用执行函数体代码时存活,调用完毕后销毁

1.4 名称空间查找优先级

在当前位置向上一层一层查找

内置名称空间=>全局名称空间=>局部名称空间

如果当前局部名称空间:局部的命名空间去-> 全局命名空间 -> 内置命名空间

如果当前在全局名称空间:全局名称空间=>内置名称空间

注意:无法向内查找,只能向外层一层一层查找

作用域

作用域即作用范围

全局作用域:内置名称空间,全局名称空间

1、全局存活

2、全局有效,被所有函数共享

局部作用域:局部名称空间

1、临时存活

2、局部有效,函数内有效

  • L(Local):最内层,包含局部变量,比如一个函数/方法内部。

  • E(Enclosing):包含了非局部(non-local)也非全局(non-global)的变量。比如两个嵌套函数,一个函数(或类) A 里面又包含了一个函数 B ,那么对于 B 中的名称来说 A 中的作用域就为 nonlocal。

  • G(Global):当前脚本的最外层,比如当前模块的全局变量。

  • B(Built-in): 包含了内建的变量/关键字等,最后被搜索。

注意:名称空间的嵌套关系是以函数定义为准生成的,与调用位置无关

def foo():
  print(x)

  
def bar():
  x = 111
  foo()
  
  
x = 100
bar()  # bar()的输出结果为100

global 与 nonlocal关键字

当局部作用域想修改成为全局作用域变量时,就需要用到global关键字

x = 1
def func():
  global x  # global关键字声明
  x = 100
  print(x)
  

print(x)  # 此时全局变量x已经被修改 x = 100
func()  #  100

nonlocal关键字用来修改嵌套作用域,即enclosing作用域,通俗的来说,即嵌套的外一层的变量,不会修改全局中的变量

def outer():
  x = 10
  def inner():
    nonlocal x  # nonlocal 关键字声明
    x = 555
    print(x)
  inner()
  print(x)
  
  
outer()  # 输出结果为555 555