python函数作用域与闭包_python之函数作用域、嵌套以及闭包

我们首先回忆一下Python代码运行的时候遇到函数是怎么做的,从Python解释器开始执行之后,就在内存中开辟里一个空间,每当遇到一个变量的时候,就把变量名和值之间对应的关系记录下来,但是当遇到函数定义的时候,解释器只是象征性的将函数名读如内存,表示知道这个函数存在了,至于函数内部的变量和逻辑,解释器根本不关心。

等执行到函数调用的时候,Python解释器会再开辟一块内存来储存这个函数里面的内容,这个时候,才关注函数里面有哪些变量,而函数中的变量回储存在新开辟出来的内存中,函数中的变量只能在函数内部使用,并且会随着函数执行完毕,这块内存中的所有内容也会被清空。

我们给这个‘存放名字与值的关系’的空间起了一个名字-------命名空间。

代码在运行伊始,创建的存储“变量名与值的关系”的空间叫做全局命名空间;

在函数的运行中开辟的临时的空间叫做局部命名空间。

在python中,名称空间三种:

全局名称空间

局部名称空间(临时)

内置名称空间

作用域:

全局作用域:作用于全局名称空间 内置名称空间

局部作用域:作用于局部名称空间(临时)

取值顺序:就近原则,单向从小到大范围

局部名称空间 ---> 全局名称空间 ---> 内置名称空间

加载顺序

内置名称空间 ---> 全局名称空间(当程序执行时) ---> 局部名称空间(当函数调用的时候)

局部名称空间 对全局名称空间的变量可以引用,但是不能改变。

如果你在局部名称空间对一个变量进行修改,那么解释器会认为你的这个变量在局部中已经定义了。

global

1.在局部名称空间声明一个全局变量

2.在局部名称空间可以对全局变量进行修改

实际中

不常用

nonlocal

相当于子函数对父函数的变量进行修改。

此变量不能是全局变量

# 在局部作用域中,对父级作用域(或者更外层作用域非全局作用域)的变量进行引用和修改,

# 并且引用的哪层,从那层及以下此变量全部发生改变。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

#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

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

#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)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值