我们首先回忆一下Python代码运行的时候遇到函数是怎么做的,从Python解释器开始执行之后,就在内存中开辟里一个空间,每当遇到一个变量的时候,就把变量名和值之间对应的关系记录下来,但是当遇到函数定义的时候,解释器只是象征性的将函数名读如内存,表示知道这个函数存在了,至于函数内部的变量和逻辑,解释器根本不关心。
等执行到函数调用的时候,Python解释器会再开辟一块内存来储存这个函数里面的内容,这个时候,才关注函数里面有哪些变量,而函数中的变量回储存在新开辟出来的内存中,函数中的变量只能在函数内部使用,并且会随着函数执行完毕,这块内存中的所有内容也会被清空。
我们给这个‘存放名字与值的关系’的空间起了一个名字-------命名空间。
代码在运行伊始,创建的存储“变量名与值的关系”的空间叫做全局命名空间;
在函数的运行中开辟的临时的空间叫做局部命名空间。
在python中,名称空间三种:
全局名称空间
局部名称空间(临时)
内置名称空间
作用域:
全局作用域:作用于全局名称空间 内置名称空间
局部作用域:作用于局部名称空间(临时)
取值顺序:就近原则,单向从小到大范围
局部名称空间 ---> 全局名称空间 ---> 内置名称空间
加载顺序
内置名称空间 ---> 全局名称空间(当程序执行时) ---> 局部名称空间(当函数调用的时候)
局部名称空间 对全局名称空间的变量可以引用,但是不能改变。
如果你在局部名称空间对一个变量进行修改,那么解释器会认为你的这个变量在局部中已经定义了。
global
1.在局部名称空间声明一个全局变量
2.在局部名称空间可以对全局变量进行修改
实际中
不常用
nonlocal
相当于子函数对父函数的变量进行修改。
此变量不能是全局变量
# 在局部作用域中,对父级作用域(或者更外层作用域非全局作用域)的变量进行引用和修改,
# 并且引用的哪层,从那层及以下此变量全部发生改变。
#global
#1,在局部名称空间声明一个全局变量。#def func2():#global name#name = 'alex'#func2()#print(name)
#2,在局部名称空间可以对全局变量进行修改。#count = 1#def func1():#global count#count = count + 1#print(count)#func1()#print(count)
global
#nonlocal#def func1():#count = 666#def func2():#print(count)#func2()#func1()
nonlocal
函数嵌套
def func1():
count = 666
def inner():
print(count)
def func2():
nonlocal count
count += 1
print('func2',count)
func2()
print('inner',count)
inner()
print('func1',count)
func1()
# 666 func2 667 inner 667 func1 667
函数名的应用:
1. 函数名就是函数的内存地址
2. 函数名可以做为变量
3. 函数名可以做为函数的参数
4. 函数名可以当作函数的返回值
5. 函数名可以做为容器类类型的元素
像上面的函数名这种,叫第一类对象
1. 可在运行期创建
2. 可用作函数参数或返回值
3. 可存入变量的实体。
1. 函数名就是函数的内存地址
# def func1():
# print(666)
#
# print(func1) #
# 2. 函数名可以做为变量
# f1 = func1
# f1()
# 3. 函数名可以做为函数的参数
# def func1():
# print(666)
#
# def func2(x):
# x() # func1()
#
# func2(func1)
# 4. 函数名可以当作函数的返回值
# def wraaper():
# def inner():
# print('----inner ')
# return inner
#
# ret = wraaper() # inner
# ret()
#
# def func2():
# print('in the func2')
#
# def func3(x):
# print('in the func3') # x = func2
# return x
#
# f1 = func3(func2) # func2
# f1()
# 5. 函数名可以做为容器类类型的元素
# def func1():
# print('in func1')
#
# def func2():
# print('in func2')
#
# def func3():
# print('in func3')
#
# l1 = [func1, func2, func3, ]
# for i in l1:
# i()
# 像上面的函数名这种,叫第一类对象
globals() 返回全局变量的一个字典
locals() 返回当前位置的局部变量的字典
# globals() locals()
# def func1():
# pass
# print(globals())
# print(locals())
def func1():
a = 2
b = 3
print(globals())
print(locals())
func1()
闭包: 内层函数对外层函数的变量(非全局变量)的引用,并返回, 这样就形成了闭包。
闭包的作用:
当程序执行时,遇到了函数执行,他会在内存中开辟一个空间,局部名称空间。如果这个函数内部形成了闭包,
那么他就不会随着函数的结束而立马消失。
# def wrapper():
# name = 'alex'
# def inner():
# print(name)
# print(inner.__closure__) # 判断是否闭包(,)
# # 不是闭包返回None
# inner()
# return inner
#
# wrapper()
name = 'alex'
def wrapper(n):
# 相当于 n = 'alex'
def inner():
print(n)
print(inner.__closure__) # 闭包
inner()
return inner
wrapper(name)