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.可以使变量常驻内存

  • 相关阅读:
    MySQL
    用python自动复制粘贴excel表里某一列的数据到另一个表中
    python操作excel小试牛刀
    python- 安装扩展包
    15分钟用ppt制作桌面整理四格壁纸
    R-算术运算符
    R-变量
    R-函数/语法-整合版
    MySQL-函数-整合版
    Python_图片对比问题汇总
  • 原文地址:https://www.cnblogs.com/zhao-ting/p/9451247.html
Copyright © 2011-2022 走看看