pytho-函数作用域

函数外部可以使用函数内部的变量?

def test():
    a = 10
    print(a)


test()   # 
print(a)  # NameError: name 'a' is not defined

代码运行的形式

python解释器开始运行之后,会在内存里面开辟一个空间,每当遇见一个变量的时候,就把变量名和值的对应关系进行记录下来,但是遇见函数的时候,解释器只是象征性的将函数名读到内存中,表示知道这个函数的存在了,至于函数内部的变量和逻辑,解释器根本不关心。
等到执行调用函数的时候,python解释器会在开辟一块内存空间来存储这个函数里面的内容,这个时候,才关心还是里面的这些变量,而函数中的变量会存储在新开辟的内存空间里面,函数中的变量只能在函数内部进行使用,并且会随着函数执行完毕,这块内存中的所以的内容也会被清空。

"存放名字和值的关系"的空间起了一个名字,叫作:命名空间。
代码开始,创建和存储"变量名和值的关系"的空间叫作全局命名空间。
在函数中运行开辟的临时的空间叫作局部命名空间。

命名空间和作用域

命名空间有下面的几种形式:

  • 全局命名空间
  • 局部命名空间
  • 内置命名空间

内置命名空间

内置命名空间中存放了python解释器为我们提供的名字:input,print,str,list,tuple...它们都是我们熟悉的,拿过来就可以用的方法。

三种命名空间之间的加载与取值顺序:
加载顺序:内置命名空间(程序运行前进行加载)\(\Rightarrow\)全局命名空间(程序运行中:从上到下加载)\(\Rightarrow\)局部命名空间(程序运行中:调用才加载)
取值顺序:

  • 在局部调用的时候:局部命名空间\(\Rightarrow\)全局命名空间\(\Rightarrow\)内置的命名空间
  • 在全局调用的时候:全局命名空间\(\Rightarrow\)内置命名空间
    在寻找变量时,从小范围去寻找,一层一层到大范围去找寻。

作用域作用域

按照生效范围分为:

  • 全局作用域:包括了名称空间和全局名称空间,在整个文件的任意位置都有被引用,全局有效
  • 局部作用域:局域名称空间,只能在局部内生效。

global和nonlocal关键字

global:

  • 声明一个全局变量
  • 在局域作用域想要对全局变量进行修改时,则可以使用global关键字(只能是字符串和数字)
def test():
    global a
    a = 10
    print(a)  # 10


test()
print(a)  # 10


count = 1
def search():
    global count
    count = 2
search()
print(count)  # 2

nonlocal:

  • 不能修改全局变量。
  • 在局部作用域中,对父级作用域(或者更外层作用域非全局作用域)的变量进行引用和修改,并且引用的哪层,从那层及以下此变量全部发生改 变。
def add_b():
    b = 42

    def do_global():
        b = 10
        print(b)

        def dd_nonlocal():
            nonlocal b
            b = b + 20
            print(b)

        dd_nonlocal()
        print(b)

    do_global()
    print(b)


add_b()

总结:
1、局部作用域改变全局变量用global, global同时还可以定义新的全局变量

2、内层函数改变外层函数变量用nonlocal, nonlocal不能定义新的外层函数变量,只能改变已有的外层函数变量

函数的嵌套和作用域链

def f1():
    print("1111")

    def f2():
        print("2222")

        def f3():
            print("3333")
        f3()
    f2()
f1() # 1111 2222 3333 
**********************************************************************************
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("in f3")
        print("in f2")
        f3()
    print("in f1")
    f2()
f1()

函数的作用域链

def f1():
    a = 1
    def f2():
        print(a)
    f2()

f1()  # 1


函数名的本质

函数名本质上就是函数的内存地址

def f1():
    a = 1
    def f2():
        print(a)
    f2()


print(f1)  # <function f1 at 0x000001ADCD0D3E18>  # 内存地址

1函数是可以被引用的

def func():
    print("function")

f = func
f()  # function

2.可以被当作容器类型的元素

def func1():
    print("function1")

def func2():
    print("function2")

def func3():
    print("function3")

def func4():
    print("function4")

func_list = [func1, func2, func3, func4]

for i in func_list:
    i()
'''
function1
function2
function3
function4
'''
posted @ 2019-08-04 20:44  yangchangjie  阅读(121)  评论(0编辑  收藏  举报