python中 什么是闭包其中的作用域

# 实例
def scope_test():
    spam = "我是 test_spam"  # 变量spam

    def do_local():  # 局部赋值
        spam = "我是本地绑定作用域local_spam"

    def do_nonlocal():  # 函数嵌套赋值,将spam定义为不是本地、不是局部变量,为自定义变量,它会保留定义函数时变量的绑定,当定义变量的作用域不可以用了,那些绑定仍然可以被调用。
        nonlocal spam   # nonlocal 关键字为:声明的变量不是局部变量, 也不是全局变量, 而是外部嵌套函数内的变量。
        spam = "我是自由变量绑定的作用域 nonlocal_spam"

    def do_global():
        global spam   # 全局赋值
        spam = "我是全局绑定作用域global_spam"

    do_local()
    print("局部作用域赋值(默认状态)不会改变scope_test 对spam的绑定作用域:   ", spam)
    do_nonlocal()
    print("函数嵌套赋值对scope_test对spam作用域的赋值:   ", spam)
    do_global()
    print("全局作用域赋值会改变模块层级的绑定:   ", spam)

scope_test()
print("这里的spam是全局没有赋值前的变量,他改变了模块层级的绑定:   ", spam)

作用域 又称 命名空间,指变量起作用的范围。
Python变量作用域可以分为四种,
分别为:
1、局部作用域(Local、简称 L)
2、嵌套作用域(Enclosed,简称 E)
3、全局作用域(Global,简称 G)
4、内置作用域(Built-in,简称 B)
*调用顺序为就近原则,LEGB
来看看其中 怎么更改其中作用域# 关键字global和nonlocal的用法说明
"""
global 关键字是用来函数 和 其他作用域中使用的全局变量

"""
"""
1/局部变量 修改 全局变量 不使用 global 关键字会报错

count = 0  # 定义全局变量count 让他初始为 0
def global_test():  #定义global_test 函数名
    count += 1      # 局部变量 count 自增 1
    print(count)    # 输出 count
global_test()       # 调用 global_test 函数
会报错 :UnboundLocalError: local variable 'count' referenced before assignment
"""

"""
2/局部变量 修改 全局变量 ,应该在局部变量中声明全局变量,这样才不会报错

count = 0  # 定义全局变量count 让他初始为 0
def global_test():  # 定义global_test 函数名
    global count    # 局部 函数 global_test内 声明全局变量
    count += 1      # 局部变量 count 自增 1
    print(count)    # 输出 count
global_test()  # 调用 global_test 函数
print(count)
"""
"""
定义一个变量 不是局部变量/全局变量/不做修改 ,调用函数输出正常

count = 0  # 定义变量count 让他初始为 0
def global_test():  # 定义global_test 函数名
    print(count)  # 输出 count
global_test()  # 调用 global_test 函数
"""
"""
nonlocal  解释为 非局部的 
nonlocal 关键字为:声明的变量不是局部变量,也不是全局变量,而是外部嵌套函数内的变量。

"""


#
# def nonlocal_test():
#     count = 0
#
#     def test2():
#         nonlocal count
#         # global count
#         # 在嵌套内的函数中 , 如果你使用了 global 就会发生报错
#         # 报错为:NameError: name 'count' is not defined  意思是 count不在本地定义中,也不是全局定义 找不到这个count 这个变量
#         # nonlocal 就是把这个count进行标记,告诉这个test2()这个函数 count 既不是本地,也不是全局,count 为自由变量
#         count += 1
#         return count
#
#     return test2
#
# val = nonlocal_test()
# print(val())
# print(val())
# print(val())
# print(val())
# print(val())
"""
def f():                     # 定义函数 f()
    count = 0                # 定义变量count 为0 ,他的作用域 在fu() 函数中为局部变量 

    def a():                 # 定义嵌套函数为a()  嵌套函数a 中 就是闭包作用域
        nonlocal count       # 将a()函数中的 count 告诉a() 他不是全局变量 也不是本地变量
        count += 1           # count 自增 1
        print(count)         # 输出count
    return a()               # a()函数 返回a的方法 
    # return a               # a  函数a 不加() 返回的是一个a的内存地址

f() 

代码注释连起来看他做了哪些事情:
1、调用函数f时,f会返回a()
2、当执行a()的时候,f函数的任务已经完成了,它占用的资源就会释放掉,这其中包括了函数f环境中定义的count变量。
3、在执行a的时候,函数f进行了释放,没有办法再去找到其中的数据。
4、像函数a中count这一类,不在本地定义域中绑定的变量,我们叫做自由变量。
5、用nonlocal标记后呢,Python就会保留自由变量的绑定(或者说定义环境)。
6、整个函数a的作用域是“count = 0”,加上a本身。
总结:a延伸了自己的作用域,这里就可以被称作“闭包”。书面意思讲解:调用一个函数X返回值一个函数y 叫闭包
"""

"""
我们学到了什么?
global / nonlocal 就是指 改变变量的作用域
global标记为 全局变量, nonlocal标记为 非全局,非本地的“自由变量”
延时作用域的函数,叫做闭包

"""

# 资料

https://realpython.com/python-scope-legb-rule/#understanding-scope

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值