• Python名称空间与闭包


    一、 名称空间(namespace)
    1. 名称空间的分类
    Python中通过提供 namespace 来实现重名函数/方法、变量等信息的识别,其一共有三种 namespace,分别为:、
        - local namespace: 作用范围为当前函数或者类方法
        - global namespace: 作用范围为当前模块
        - build-in namespace: 作用范围为所有模块

    2. 名称空间的查找顺序
        1. local namespace
        2. global namespace
        3. build-in namespace

    3. 作用域
    全局作用域:内置名称空间,全局名称空间
    局部作用:局部名称空间
    全局作用域的变量:全局有效,在任何位置都能被访问到,除非del删掉,否则会一直存活到文件执行完毕
    局部作用域的变量:局部有效,只能在局部范围调用,只在函数调用时才有效,调用结束就失效

    x=1000
    def func(y):
            x=2
            print(locals())                #    {'x': 2, 'y': 1}    局部命名空间变量,作用于就在本函数内
            print(globals())              
            #    全局名称空间变量:{'__package__': None, 'x': 1000, '__file__': '...', '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x008059B0>, '__doc__': None, '__name__': '__main__', '__builtins__': <module 'builtins' (built-in)>, 'func': <function func at 0x0136D7C8>, '__spec__': None, '__cached__': None}
    
    func(1)
    print(locals())
    print(globals())
    print(globals() is locals())    #    True
    locals 在函数外的全局空间中所以和globals()内容一致

    二、 闭包(closure)
    1. 创建闭包
    在Python中创建一个闭包可以归结为以下三点:
        - 闭包函数必须有内嵌函数
        - 内嵌函数需要引用上一级函数namespace中的变量
        - 闭包函数必须返回内嵌函数


    2. 示例

    形成闭包之后,闭包函数会获得一个非空的__closure__属性

    __closure__属性是一个元祖,元组里面的对象为cell对象,而访问cell对象的cell_contents属性则可以得到闭包变量的当前值

    x=1
    y=2
    def f1():
      x=4
      def f2():
        print(x,y)
      return f2
    f
    =f1() print(dir(f))               # 从结果看出f对象中包含__closure__属性 print(f.__closure__)           # __closure__对应的元祖中,包含cell类型的对象 print(f.__closure__[0])         # cell类型的对象 print(f.__closure__[0].cell_contents) # cell的值 ----------------------------------------------------------------------------------- 结果: 4 2 ['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__'] (<cell at 0x014659D0: int object at 0x1D468A00>,) <cell at 0x014659D0: int object at 0x1D468A00> 4


    3. 结论
    闭包的原理,当内嵌函数引用了包含它的函数(enclosing function)中的变量后,这些变量会被保存在enclosing function的__closure__属性中,成为enclosing function本身的一部分;也就是说,这些变量的生命周期会和enclosing function一样。

  • 相关阅读:
    springcloud随便写点
    简单的数组排序
    简单wait(),notify()方法
    热词
    mysql日期函数
    springboot和jsp,以及引入jquery
    用户,权限,角色的关系
    通过字节码获取到的方法
    数据库并发事物
    在spring的业务层获取request,response
  • 原文地址:https://www.cnblogs.com/yunweixiaoxuesheng/p/8962137.html
Copyright © 2020-2023  润新知