名称空间和作用域

名称空间和作用域

一、名称空间

名称空间:就是存放名字和对象映射/绑定关系的地方(存放名字的空间)

​ 如果你想访问一个变量值,必须先访问对应的名称空间拿到名字和对应的内存地址的绑定地址

  • 名称空间的分类

    • 内置名称空间

    Python提前给你定义完的名字,就是存在内置名称空间,比如内建函数名

    >>> max
    <built-in function max>
    >>>
    >>> print
    <built-in function print>
    >>>
    >>> input
    <built-in function input>
    
    • 全局名称空间

    存放于文件级别的名字,就是全局名称空间

    if、while、for内部定义的名字执行之后都存放于全局名称空间

    • 局部名称空间

    函数内部定义的所有名字都市存放于当前函数的内置名称空间

    def foo(x):
        y = 1 	#调用函数时,才会执行函数代码,名字x和y都存放于该函数的局部名称空间中
    
  • 名称空间的顺序

    • 加载顺序为:内置 > 全局 > 内置
    • 查找顺序为:局部 > 全局 > 内置

    函数内部使用的名字,定义阶段已经规定死了,与调用位置无关

  • 生命周期

    • 内置名称空间

    在Python解释器启动的时候生效,关闭解释器的时候失效

    • 全局名称空间

    当你启动当前这个py文件的时候生效,当页面代码执行结束之后失效

    • 局部名称空间

    当你调用当前函数时生效,函数体最后一行代码执行结束之后失效

二、作用域

按照名字作用范围的不同可以将三个名称空间划分为两个区域:

  • 全局作用域

位于全局名称空间、内建名称空间中的名字属于全局范围,该范围内的名字全局存活(除非被删除)、全局有效(在任意位置都可以使用)

【全局可以调用的名字就存放于全局作用域】【内置名称空间+全局名称空间】

x = 100
def foo():
    x = 300	#函数调用时产生局部作用域的名字x
foo()
print(x)	#在全局找x,结果为100

在全局作用域查找名字时,先查找全局名称空间,没有找到,再查找内置名称空间,最后都没有找到就会抛出异常

  • 局部作用域

位于局部名称空间中的名字属于局部范围。该范围内的名字临时存活(在函数调用时临时生成,函数调用结束后释放)、局部有效(只能在函数内使用)

【局部可以调用的名字就存放于局部作用域】【局部名称空间】

x = 100	#全局作用域的名字x
def foo():
    x = 300	#局部作用域的名字x
    print(x)	#在局部找x
foo()	#结果为300

在局部作用域查找名字时,先查找全局名称空间,没有找到,再查找内置名称空间,最后都没有找到就会抛出异常

  • 关键字global

声明全局变量

x = 1
def foo():
    global x	#声明x为全局名称空间的名字
    x = 2
foo()
print(x)
2
  • 关键字nonlocal

在局部名称空间声明局部变量,在局部修改上层函数的变量

只有可变类型可以在局部修改外部变量的值

def f1():
    x = 2
    def f2():
        nonlocal x
        x = 3
    f2()	#调用f2(),修改f1作用域中名字x的值
    print(x)	#在f1作用域查看x
f1()
3

nonlocal x 会从当前函数的外层函数开始一层层去查看名字x,若是一直到最外层函数都找不到,则会抛出异常

posted @ 2019-11-12 17:51  YGZICO  阅读(127)  评论(0编辑  收藏  举报