名称空间与作用域

一、名称空间

名称空间:就是名字与地址的对应关系,可以被python解释器遍历查找,采用堆栈存储方式

队列存储方式:先进先出
堆栈存储方式:先进后出,优先访问到的是最后添加到结构中的变量

在内置、全局、局部三个位置,只要出现了变量的定义,一定产生了自己名称空间中的民资,这些名字之间没有冲突

三种名称空间:

1. 内置名称空间:系统级,一个,随解释器执行而产生,解释器停止而销毁
2. 全局名称空间:文件级,多个,随所属文件加载而产生,稳健运行完毕而销毁
3. 当前名称空间:函数级,多个,随所属函数执行而产生,函数执行完毕而销毁

【注】文件的if,while,for,with这些能产生缩减的关键字并不能产生名称空间

加载顺序:内置名称空间 > 全局名称空间 > 当前名称空间
在局部调用:局部命名空间 > 全局命名空间 > 内置命名空间

二、函数嵌套

2.1 函数的嵌套调用

def max2(x,y):
    m  = x if x>y else y
    return m

def max4(a,b,c,d):
    res1 = max2(a,b)
    res2 = max2(res1,c)
    res3 = max2(res2,d)
    return res3

# max4(23,-7,31,11)

2.2 函数的嵌套定义

概念:在一个函数的内部定义另一个函数


为什么要有函数的嵌套定义:

1)函数fn2想直接使用fn1函数的局部变量,可以将fn2直接定义到fn1的内部,这样fn2就可以直接访问fn1的变量

2)函数fn2名字就变成fn1的局部变量了,正常只能在fn1内部使用,想在外部使用,可以将fn2函数对象作为fn1函数的返回值

3)在外部也用同名的变量fn2来接收fn1函数 的执行结果(fn1函数的返回值),那么fn2也就是在外部被调用

def f1():
    def f2():
        def f3():
            print("in f3")
        print("in f2")
        f3()
    print("in f1")
    f2()
    
f1()
def f1():
    def f2():
        def f3():
            print('from f3')
        f3()
    f2()

f1()
f3() #报错,为何?

三、作用域

3.1 作用域范围

作用域就是作用范围,按照生效范围可以分为全局作用域和局部作用域。

全局作用域:包含内置名称空间、全局名称空间,在整个文件的任意位置都能被引用、全局有效

局部作用域:局部名称空间,只能在局部范围内生效

【注】
1. 不同作用域之间名字不冲突,已达到名字的重用
2. 每个作用域优先使用自己作用域的名字,没有再找更大的名称空间的名字,直到内置,还没有就报错
3. 查找顺序:局部作用域 > 嵌套作用域 > 全局作用域 > 内置作用域

print(len)              # <built-in function len>
len = 10
def f1():
    len = 20
    print(len)          # 20
    def f2():
        len = 30
        print(len)      # 30
    f2()
f1()
print(len)              # 10  

3.2 global关键字

1.作用:将局部的变量提升为全局变量
# 1.全局没有同名变量,直接提升局部变量为全局变量
# 2.有同名全局变量,就是统一全局与局部的同名变量
#       -- 如果局部想改变全局变量的值(发生地址的变化),可以用global声明该变量

num = 888
def fn1():
    global num
    # print(num)
    # 没有global修饰,num就是自己局部的变量
    # 有global修饰,num就是全局的num,全局中只能出现一个num,如果出现了值的改变,大家一起变
    num = 666
def fn2():
    print(num)  # 666
fn1()
fn2()

3.3 nolocal关键字

1.作用:将局部的变量提升为全局变量
# 1.全局没有同名变量,直接提升局部变量为全局变量
# 2.有同名全局变量,就是统一全局与局部的同名变量
#       -- 如果局部想改变全局变量的值(发生地址的变化),可以用global声明该变量

num = 888
def fn1():
    global num
    # print(num)
    # 没有global修饰,num就是自己局部的变量
    # 有global修饰,num就是全局的num,全局中只能出现一个num,如果出现了值的改变,大家一起变
    num = 666
def fn2():
    print(num)  # 666
fn1()
fn2()

 

posted on 2020-05-15 23:11  软饭攻城狮  阅读(112)  评论(0编辑  收藏  举报

导航