zoukankan      html  css  js  c++  java
  • day4_python之名称空间与作用域、闭包函数、嵌套函数

    一、名称空间与作用域

    名称空间:存放名字的地方,准确的说名称空间是存放名字与变量值绑定关系的地方
    
    内置名称空间:在python解释器启动时产生,存放一些python内置的名字
    全局名称空间:在执行文件时产生,存放文件级别定义的名字
    x=1
    def func():
        y=2
        def f1():pass
        print
    
    
    import os
    
    class Foo:
        pass
    
    if x==1:z=3
    
    del x
    
    
    局部名称空间:在执行文件的过程中,如果调用了函数,则会产生该函数的局部名称空间
    用来存放该函数内定义的名字,该名字在函数调用时生效,在函数调用结束后失效
    
    
    
    加载顺序:内置---》全局---》局部
    
    
    优先掌握一:名字的查找顺序是:局部-》全局-》内置
    
    # max=1
    def foo():
        max=2
        # print(max)
    
    foo()
    print(max)
    
    
    
    
    x=0
    def f1():
        x=1
        def f2():
            x=2
            def f3():
                x=3
                print(x)
            f3()
        f2()
        print('=f1========',x)
    
    
    f1()
    
    
    
    
    def func1():
        print('from func1')
    
    def func1():
        print('=====?>')
    
    func1()
    
    x=1
    x=10
    print(x)
    View Code

    1、什么是名称空间?

    #名称空间:存放名字的地方,三种名称空间,(之前遗留的问题x=1,1存放于内存中,那名字x存放在哪里呢?名称空间正是存放名字x与1绑定关系的地方)

    2、名称空间的加载顺序

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

    3、名字的查找顺序

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

    二、作用域

    作用域:作用的范围,
    全局作用域:全局存活,全局有效:globals()
    max=1111111
    def f1():
        def f2():
            def f3():
                def f4():
                    # print(x)
                    print(max)
                f4()
            f3()
        f2()
    
    
    f1()
    局部作用域:临时存活,局部有效:locals()
    
    x=11111111111111111111111111111111111111111111
    
    def f1():
        x=1
        y=2
        def f2():pass
        # print(locals())
        print(globals())
    
    f1()
    print(locals() is globals())
    print(locals())
    
    print(dir(globals()['__builtins__']))
    
    
    --------------------------------------------------
    global nonlocal掌握    :global 修改全局的
    x=1
    def f1():
        global x       明确声明x就是全局的x ,所以就会把全局的x=1,改成局部的x=2。
        x=2
    
    f1()
    print(x)
    -----------------------------------------------
    
    l=[]
    def f2():
        l.append('f2')    能直接把l的值改‘f2’,因为l是列表,列表是可变类型。
    
    f2()
    print(l)
    
    ----------------------------------------------------
    x=0
    def f1():
        # x=1
        def f2():
            # x=2
            def f3():
               # global x
               nonlocal x      //修改的是函数内部正上方的那个X,所有x被修改成2.只在函数内部有效。
               x=3
            f3()
            # print(x)
        f2()
        print(x)
    f1()
    print(x)
    
    -----------------------------------------------------
    
    
    优先掌握二:作用域关系,在函数定义时就已经固定
    ,与调用位置无关,在调用函数时,必须必须必须
    回到函数原来定义的位置去找作用域关系
    
    x=1
    def  f1():
        def f2():
            print(x)
            return f2
    def foo(func):
        x=300000
        func()
    res=f1()
    print(res)
    func=f1()
    print(func)
    x=10000000
    func()
    x=10000000
    
    
    
    def foo(func):
        x=300000000
        func() #f2()
    x=10000000000000000000000
    
    
    
    foo(f1())
    # x=10000000000000000000000
    # foo(f1())
    
    
    
    
    
    
    
    x=1
    def f1():
        global x
        x=2
    
    f1()
    print(x)
    View Code
    #1、作用域即范围
            - 全局范围(内置名称空间与全局名称空间属于该范围):全局存活,全局有效
          - 局部范围(局部名称空间属于该范围):临时存活,局部有效
    #2、作用域关系是在函数定义阶段就已经固定的,与函数的调用位置无关,如下
    x=1
    def f1():
        def f2():
            print(x)
        return f2
    x=100
    def f3(func):
        x=2
        func()
    x=10000
    f3(f1())
    
    #3、查看作用域:globals(),locals()
    
    
    LEGB 代表名字查找顺序: locals -> enclosing function -> globals -> __builtins__
    locals 是函数内的名字空间,包括局部变量和形参
    enclosing 外部嵌套函数的名字空间(闭包中常见)
    globals 全局变量,函数定义所在模块的名字空间
    builtins 内置模块的名字空间
    

    三、global与nonlocal关键字  

    global nonlocal掌握    :global 修改全局的
    x=1
    def f1():
        global x       明确声明x就是全局的x ,所以就会把全局的x=1,改成局部的x=2。
        x=2
    
    f1()
    print(x)
    -----------------------------------------------
    
    l=[]
    def f2():
        l.append('f2')    能直接把l的值改‘f2’,因为l是列表,列表是可变类型。
    
    f2()
    print(l)
    
    ----------------------------------------------------
    x=0
    def f1():
        # x=1
        def f2():
            # x=2
            def f3():
               # global x
               nonlocal x      //修改的是函数内部正上方的那个X,所有x被修改成2.只在函数内部有效。
               x=3
            f3()
            # print(x)
        f2()
        print(x)
    f1()
    print(x)
    

    四、闭包函数

     1、什么是闭包?

    复制代码
    #内部函数包含对外部作用域而非全局作用域的引用
    
    #提示:之前我们都是通过参数将外部的值传给函数,闭包提供了另外一种思路,包起来喽,包起呦,包起来哇
    
            def counter():
                n=0
                def incr():
                    nonlocal n
                    x=n
                    n+=1
                    return x
                return incr
    
            c=counter()
            print(c())
            print(c())
            print(c())
            print(c.__closure__[0].cell_contents) #查看闭包的元素
    复制代码

    2、闭包的意义与应用

    复制代码
    #闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域
    #应用领域:延迟计算(原来我们是传参,现在我们是包起来)
        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'))
    复制代码
    大前提:作用域关系,在函数定义时就已经固定
    ,与调用位置无关,在调用函数时,必须必须必须
    回到函数原来定义的位置去找作用域关系
    
    
    闭包函数:
    1. 定义在函数内部的函数
    2. 包含对外部作用域名字的引用,而不是对全局作用域名字的引用
    那么该内部函数就称为闭包函数
    x=1
    def  f1():
        x=11111111111
        def f2():
            print(x)
        return f2
    
    func=f1()
    
    
    x=1000
    func()
    
    def foo():
        x=12312312312312312312312312312312312313123
        func()
    
    
    foo()
    
    
    def deco():
        x=123123123123
        def wrapper():
            print(x)
        return wrapper
    
    func=deco()
    
    
    func()
    
    
    #闭包函数的应用:惰性计算
    import requests #pip3 install requests  安装pip3
    
    def get(url):
        return requests.get(url).text
    
    print(get('https://www.python.org'))
    print(get('https://www.python.org'))
    print(get('https://www.python.org'))
    print(get('https://www.python.org'))
    
    def index(url):
        # url='https://www.python.org'
        def get():
            # return requests.get(url).text
            print(requests.get(url).text)
    
        return get
    
    python_web=index('https://www.python.org')
    baidu_web=index('https://www.baidu.com')
    
    python_web()
    baidu_web()
    
    
    
    
    
    
    name='egon'
    def index(url):
        x=1
        y=2
        def wrapper():
            # x
            # y
            # return requests.get(url).text
            print(name)
        return wrapper
    
    python_web=index('https://www.python.org')
    
    # print(python_web.__closure__[0].cell_contents)
    print(python_web.__closure__)
    # print(python_web.__closure__[0].cell_contents)
    # print(python_web.__closure__[1].cell_contents)
    # print(python_web.__closure__[2].cell_contents)
    View Code

    五、嵌套函数

    函数的嵌套调用:在调用一个函数的过程中,又调用了其他函数
    def bar():
        print('from nbar')
    
    def foo():                       #再调用一个函数的过程中,又去调用了另外一个函数
        print('from foo')
        bar()
    
    foo()
    
    -----------------------------------------
    求两个值最大的函数
    def max2(x,y):
        if x > y:
            return x
        else:
            return y
    
    
    def max4(a,b,c,d):      求四个值的最大值
        res1=max2(a,b)      把a b 传进去会得到第一个结果
        res2=max2(res1,c)   再调用一次,拿着这一次得到的结果在跟c进行比较
        res3=max2(res2,d)
        return res3         得到res3最终的结果
    
    
    print(max4(1,2,3,-1))
    
    -------------------------------------------------
    函数的嵌套定义:在一个函数的内部,又定义另外一个函数
    
    def f2():
        print('from f2')
    
    def f1():
        x=1                    函数内部定义的名字,只是在函数被调用的时候生效。
        # def f2()
        #     print('from f2')
        f2()
    
    f1()
    

      

  • 相关阅读:
    Redis存储对象(序列化和反序列化)
    JAVA中关于set()和get()方法的理解以及使用
    5W1H分析法
    Spring AOP的理解(通俗易懂)。
    Notepad++ 使用步骤,熟练掌握notepad++的使用技巧,无疑会大大提升专业技能。以及快捷键操作
    Int,String,Integer,double之间的类型的相互转换
    Ajax局部刷新和全局刷新的区别
    GET和POST都是什么时候用?
    ajax为什么需要json格式响应数据?
    final fially finalize区别
  • 原文地址:https://www.cnblogs.com/xiechao621/p/8001226.html
Copyright © 2011-2022 走看看