函数的名称空间与作用域

一、名称空间

   1、命名空间一共分为三种:

     全局命名空间:是在程序从上到下被执行的过程中依次加载进内存里面,放置了我们设置的所有变量名和函数名;在全局命名空间中,可以使用内置命名空间中的名字,但是不能用局部中使用。

     局部命名空间:就是函数定义的名字,当调用函数的时候才会产生这个名称空间,随着函数的执行结束而消失;在局部命名空间中,可以使用全局、内置命名空间中的名字。

     内置命名空间:在python解释器一启动就可以使用的名字,这个是存储在内置命名空间中的,内置名字在启动解释器的时候被加载到内存中;在内置命名空间中,不能使用全局和局部的名字。

  2、命名空间之间的加载与取值顺序:

    加载顺序:内置命名空间(程序运行前加载)->全局命名空间(程序运行中:从上到下加载)->局部命名空间(程序运行中:调用时才加载)

    在正常情况下,直接使用内置的名字,当我们在全局定义了和内置名字空间中同名的名字时,会使用全局的名字

    取值:

    在局部调用:局部命名空间->全局命名空间->内置命名空间

         在全局调用:全局命名空间->内置命名空间

    3、命名空间的查找顺序

    命名空间的查找顺序
      a) 如果在函数内调用一个变量,先在局部命名空间查找,如果找到则停止查找。否则在全局命名空间查找,如果还是没找到,则查找内置命名空间。如果以上三个命名都未找到,则会报错。
      b) 如果在函数外调用一个变量,则在全局命名空间,局部命名空间此时不可见,如果找到则停止查找,否则到内置命名空间中查找。如果两者都找不到,则报错。只有当局部命名空间内,使用global 关键字声明了一个变量时,查找顺序则是 a的查找顺序。实例如下:

#!/usr/bin/python
# -*- encodeing:utf-8 -*-

name = 'caoyf'
def func():
    #global name
    name = 'Fangsw'
    print(name)
func()
print(name)
查找顺序

 二、作用域

  1、作用域说明:作用域是小范围作用域可以使用大范围的变量,但是反之不行,他是单向的。

    全局作用域 —— 作用在全局 —— 内置和全局名字空间中的名字都属于全局作用域  ——globals() 
    globals 永远打印全局的名字

对于不可变数据类型 在局部可以是查看全局作用域中的变量
      但是不能直接修改
      如果想要修改,需要在程序的一开始添加global声明
      如果在一个局部(函数)内声明了一个global变量,那么这个变量在局部的所有操作将对全局的变量有效
a = 1
def func():
    global a
    a = 2
func()
print(a)
#此时结果显示:2      因为函数内声明了变量a=2        若将global a #注释掉,则print(a)=1
global关键字

  2、局部作用域 —— 作用在局部 —— 函数(局部名字空间中的名字属于局部作用域) ——locals()

    locals 输出什么 根据locals所在的位置
    locals 返回一个名字/值对的字典。这个字典的键字是字符串形式的变量名字,字典的值是变量的实际值。
#!/usr/bin/python
# -*- encodeing:utf-8 -*-
# a = 1
# b = 2
# def func():
#     x = 'aaa'
#     y = 'bbb'
#     print(locals())
#     print(globals())
# 
# func()
        # 此时locals是在局部作用域内,所以显示是{'y': 'bbb', 'x': 'aaa'}

# a = 1
# b = 2
# def func():
#     x = 'aaa'
#     y = 'bbb'
# print(locals())
# print(globals())
#
# func()
           #  此时locals是在全局作用域内,所以显示的是全局的名字
locals关键字

  3、函数的嵌套:

    函数嵌套的定义:内部函数可以使用外部函数的变量。

#!/usr/bin/python
# -*- encodeing:utf-8 -*-
a = 1
def outer():
    a = 1
    def inner():
        a = 2
        def inner2():
           # nonlocal a  #声明了一个上面第一层局部变量  a=2
            a = 1   #不可变数据类型的修改
            print('+',a)
        inner2()
        print('##a## : ', a)
    inner()
    print('**a** : ',a)

outer()
print('全局 :',a)打印显示:     + 1
                                ##a## :  2
                                **a** :  1
                                全局 : 1
nonlocal关键

    nonlocal只能用于局部变量,找上层离当前函数最近的局部变量。

    声明了nonlocal的内部函数的变量修改会影响到,离当前函数最近一层的局部变量。

    对全局无效,对局部也只是对最近一层有影响。

 

 

 
posted @ 2018-02-01 17:10  曹艳飞  阅读(211)  评论(0编辑  收藏  举报