zoukankan      html  css  js  c++  java
  • 名称空间和作用域、闭包

    一 名称空间

    一 定义

    名称空间:存放名字的地方,三种名称空间

    (x=1,1存放于内存中,那名字x存放在哪里呢?名称空间正是存放名字x与1绑定关系的地方)

    二 名称空间的加载顺序

    python test.py
    #1、python解释器先启动,因而首先加载的是:内置名称空间
    #2、执行test.py文件,然后以文件为基础,加载全局名称空间
    #3、在执行文件的过程中如果调用函数,则临时产生局部名称空间

    三 名字的查找顺序

    局部名称空间--->全局名称空间--->内置名称空间
    
    #需要注意的是:在全局无法查看局部的,在局部可以查看全局的,如下示例
    
    # max=1
    def f1():
        # max=2
        def f2():
            # max=3
            print(max)
        f2()
    f1()
    print(max) 

    二 作用域

    一 作用域即范围
    - 全局范围(内置名称空间与全局名称空间属于该范围):全局存活,全局有效
    - 局部范围(局部名称空间属于该范围):临时存活,局部有效

    二 作用域关系

    作用域关系是在函数定义阶段就已经固定的,与函数的调用位置无关,如下

    x=1
    def f1():
        def f2():
            print(x)
        return f2
    x=100
    def f3(func):
        x=2
        func()
    x=10000
    f3(f1())        

    三 查看作用域:globals(),locals()

    LEGB 代表名字查找顺序: locals -> enclosing function -> globals -> __builtins__
    locals 是函数内的名字空间,包括局部变量和形参
    enclosing 外部嵌套函数的名字空间(闭包中常见)
    globals 全局变量,函数定义所在模块的名字空间
    builtins 内置模块的名字空间

    三 global和nonlocal关键字

    global

    global表示. 不再使用局部作用域中的内容了. 而改用全局作用域中的变量.

    nonlocal

    nonlocal表示在局部作用域中, 调用父级命名空间中的变量.

    四 闭包

    定义

    内部函数包含对外部作用域而非全局作用域的引用

    def counter():
        n = 0
    
        def incr():
            nonlocal n
            x = n
            n += 1
            return x
    
        return incr
    
    
    c = counter()
    print(c())
    print(c())
    print(c.__closure__[0].cell_contents)  # 查看闭包的元素

    闭包的意义和应用

    闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域

    应用领域:延迟计算(原来我们是传参,现在我们是包起来)

    from urllib.request import urlopen
    
    def index(url):
      def get():
        return urlopen(url).read()
      return get
    
    baidu=index('http://www.baidu.com')
    print(baidu().decode('utf-8'))

     检查闭包:__closure__

    使用函数名.__closure__返回cell就是 闭包. 返回None就不是闭包

    def func1():
        name = "zhao"
        def func2():
            print(name) # 闭包
        func2()
        print(func2.__closure__) # (<cell at 0x10c2e20a8: str object at0x10c3fc650>,)
    func1()

    好处:

      1.保护你的变量不受外部影响

      2.可以使变量常驻内存

  • 相关阅读:
    UVA.12096 The SetStack Computer ( 好题 栈 STL混合应用)
    HDOJ(HDU).1412 {A} + {B} (STL SET)
    UVA.10474 Where is the Marble ( 排序 二分查找 )
    HDOJ(HDU).1754 I Hate It (ST 单点替换 区间最大值)
    HDOJ(HDU).1166 敌兵布阵 (ST 单点更新 区间求和)
    17 西安
    17 沈阳
    13 南京
    10/11 作战会议
    2019牛客国庆集训派对day5
  • 原文地址:https://www.cnblogs.com/zhao-ting/p/9451247.html
Copyright © 2011-2022 走看看