美文网首页
07_Python函数进阶_全栈开发学习笔记

07_Python函数进阶_全栈开发学习笔记

作者: 豆行僧 | 来源:发表于2018-10-19 15:27 被阅读0次

    # 1. 命名空间

    ## 1.1 命名空间的种类

    命名空间共有有三种

    1) 内置命名空间 —— python解释器

    就是python解释器一启动就可以使用的名字存储在内置命名空间中

    内置的名字在启动解释器的时候被加载进内存里

    <br>

    2) 全局命名空间 —— 我们写的代码但不是函数中的代码

    是在程序从上到下被执行的过程中依次加载进内存的

    放置了我们设置的所有变量名和函数名

    <br>

    3) 局部命名空间 —— 函数

    就是函数内部定义的名字

    当调用函数的时候,才会产生这个名称空间,随着函数执行的结束,这个命名空间就又消失了。

    <br>

    ## 1.2 三种命名空间之间的加载与取值顺序

    加载顺序:内置命名空间(程序运行前加载)->全局命名空间(程序运行中:从上到下加载)->局部命名空间(程序运行中:调用时才加载)

    * 在局部:可以使用全局、内置命名空间中的名字

    * 在全局:可以使用内置命名空间中的名字,但是不能用局部中使用

    * 在内置:不能使用局部和全局的名字的

    <br>

    ## 1.3 命名空间的其他说明

    1) 在正常情况下,直接使用内置的名字

    2) 当我们在全局定义了和内置名字空间中同名的名字时,会使用全局的名字

    3) 当我自己有的时候 我就不找我的上级要了

    4) 如果自己没有,就找上一级要,上一级没有再找上一级,如果内置的名字空间都没有,就报错

    5) 多个函数应该拥有多个独立的局部名字空间,不互相共享

    范例1:(对应1、2、3、4)

    ```python

    def max(l):

        print("in max func")

    print(max([1,2,3]))

    ```

    执行结果

    ```

    in max func

    None

    ```

    <br>

    范例2:(对应4)

    ```

    def input():

        print("in inpput now")

    def func():

        input()

    func()

    ```

    执行结果

    ```

    in inpput now

    ```

    <br>

    范例3:(对应4)

    ```python

    def input():

        print("in inpput now")

    def func():

        input = 1

        print(input)

    func()

    ```

    执行结果

    ```

    1

    ```

    <br>

    范例4:(对应5)

    ```python

    def fun1():

        a = 1

    def func2():

        print(a)

    print(func2())

    ```

    执行结果

    ```

    Traceback (most recent call last):

      File "E:/python_project/S9/hello.py", line 8, in <module>

        print(func2())

      File "E:/python_project/S9/hello.py", line 6, in func2

        print(a)

    NameError: name 'a' is not defined

    ```

    ----------

    # 2 作用域

    ## 2.1 作用域的种类

    作用域共两种

    1) 全局作用域 —— 作用在全局 —— 内置和全局名字空间中的名字都属于全局作用域  —— globals()

    范例1:

    ```python

    a = 1

    def func():

        print(a)

    func()

    ```

    执行结果:

    ```

    1

    ```

    <br>

    * 对于不可变数据类型,在局部可以查看全局作用域中的变量,但是不能直接修改

    * 如果想要修改,需要在程序的一开始添加global声明

    * 如果在一个局部(函数)内声明了一个global变量,那么这个变量在局部的所有操作将对全局的变量有效

    范例2:global关键字(但使用global方式不安全,尽量少用)

    ```python

    a = 1

    def func():

        global a

        a += 1

    func()

    print(a)

    ```

    执行结果:

    ```

    2

    ```

    <br>

    2) 局部作用域 —— 作用在局部 —— 函数(局部名字空间中的名字属于局部作用域) —— locals()

    <br>

    ## 2.2 作用域的方法两则(不常用)

    globals() 永远打印全局的名字

    locals() 输出什么 根据locals所在的位置,在全局输出全局,在局部输出局部

    范例:

    ```python

    a = 1

    b = 2

    def func():

        x = "aaa"

        y = "bbb"

        print(locals())

    func()

    print(globals())

    ```

    执行结果:

    ```

    {'x': 'aaa', 'y': 'bbb'}

    {'a': 1, '__package__': None, '__builtins__': <module 'builtins' (built-in)>, '__spec__': None, '__file__': 'D:/temp_study/python01/test.py', '__loader__': <_frozen_importlib.SourceFileLoader object at 0x0000000003C64D68>, 'b': 2, '__name__': '__main__', 'func': <function func at 0x000000000331CB70>, '__doc__': None, '__cached__': None}

    ```

    ----------

    # 3 函数的嵌套与作用域链

    ## 3.1 函数的嵌套调用

    范例:

    ```python

    def my_max(a,b):

        return a if a > b else b

    def three_max(x,y,z):    # 函数的嵌套调用

        c = my_max(x,y)

        return my_max(c,z)

    print(three_max(1,2,3))

    ```

    执行结果

    ```

    3

    ```

    <br>

    ## 3.2 函数的嵌套定义

    1) 函数嵌套定义的正常流程

    范例:

    ```python

    def outer():    # 第一步

        def inner():    # 第三步

            print("inner")    # 第五步

        inner()    # 第四步

    outer()    # 第二步

    ```

    执行结果

    ```

    inner

    ```

    <br>

    2) 内部函数可以使用外部函数的变量

    范例:

    ```

    def outer():

        a = 1

        def inner():

            print(a)

            print("inner")

        inner()

    outer()

    ```

    执行结果

    ```

    1

    inner

    ```

    <br>

    3) 三层嵌套

    范例1:

    ```

    def outer():

        a = 1

        def inner():

            print(a)

            print("inner")

            def inner2():

                print("inner2")

            inner2()

        inner()

    outer()

    ```

    执行结果:

    ```

    1

    inner

    inner2

    ```

    <br>

    范例2:

    ```python

    def outer():

        a = 1

        def inner():

            b = 2

            print(a)

            print("inner")

            def inner2():

                print(a,b)

                print("inner2")

            inner2()

        inner()

    outer()

    ```

    执行结果:

    ```

    1

    inner

    1 2

    inner2

    ```

    <br>

    ### 3.2.1 nonlocal()

    nonlocal 只能用于局部变量 找上层中离当前函数最近一层的局部变量。

    声明了nonlocal的内部函数的变量修改会影响到离当前函数最近一层的局部变量。

    对全局:无效

    对局部:也只是对最近的一层有影响

    范例1:

    ```

    a = 1    # 这是全局变量

    def outer():

        a = 1    # 这是局部变量

        def inner():

            b = 2

            print(a)

            print("inner")

            def inner2():

                nonlocal a    # 声明了一个上面第一层局部变量(离它最近的局部变量)

                a += 1    # 不可变数据类型的修改

                print("inner2")

            inner2()

        inner()

        print("**a** :",a)

    outer()

    print("全局:",a)

    ```

    执行结果

    ```

    1

    inner

    inner2

    **a** : 2

    全局: 1

    ```

    <br>

    范例2:

    ```python

    a = 1

    def outer():

        a = 1

        def inner():

            a = 2

            print(a)

            print("inner")

            def inner2():

                nonlocal a

                a += 1

                print("inner2")

            inner2()

            print("##a##:",a)

        inner()

        print("**a** :",a)

    outer()

    print("全局:",a)

    ```

    执行结果

    ```

    2

    inner

    inner2

    ##a##: 3

    **a** : 1

    全局: 1

    ```

    <br>

    范例3:

    ```python

    a = 0

    def outer():

        # a = 1

        def inner():

            a = 2

            def inner2():

                nonlocal a

                print(a)

            inner2()

        inner()

    outer()

    ```

    执行结果

    ```

    2

    ```

    <br>

    ## 3.3 作用域链

    在内部函数使用变量的时候,是从小局部到大局部到全局到内置名字的过程一级一级往上找,找到最近的一个就使用----作用域链

    范例1:

    ```python

    def f1():

        a = 1

        def f2():

            print(a)

        f2()

    f1()

    ```

    执行结果:

    ```

    1

    ```

    <br>

    范例2:

    ```python

    def f1():

        a = 1

        def f2():

            def f3():

                print(a)

            f3()

        f2()

    f1()

    ```

    执行结果:

    ```

    1

    ```

    <br>

    范例3:

    ```python

    def f1():

        a = 1

        def f2():

            a = 2

        f2()

        print('a in f1 : ',a)

    f1()

    ```

    执行结果:

    ```

    a in f1 :  1

    ```

    ----------

    # 4 函数名的本质

    函数名本质上就是函数的内存地址

    范例1:可以被引用

    ```python

    def func():

        print(123)

    # func()  #函数名就是内存地址

    func2 = func    # 函数名可以赋值

    func2()

    ```

    执行结果

    ```

    123

    ```

    <br>

    范例2:可以被当作容器类型的元素

    ```python

    def func():

        print(123)

    func2 = func

    func2()

    l = [func,func2]    # 函数名可以作为容器类型的元素

    print(l)

    for i in l:

        i()

    ```

    执行结果

    ```

    123

    [<function func at 0x000002604CB969D8>, <function func at 0x000002604CB969D8>]

    123

    123

    ```

    <br>

    范例3:可以当作函数的参数

    ```python

    def func():

        print(123)

    def wahaha(f):

        f()

    wahaha(func)    # 函数名可以作为函数的参数

    ```

    执行结果

    ```

    123

    ```

    <br>

    范例4:可以当作函数的返回值

    ```

    def func():

        print(123)

    def wahaha(f):

        f()

        return f          #函数名可以作为函数的返回值

    qqxing = wahaha(func)  # 函数名可以作为函数的参数

    qqxing()

    ```

    执行结果

    ```

    123

    123

    ```

    `不明白?那就记住一句话,就当普通变量用`

    第一类对象(first-class object)指

    1.可在运行期创建

    2.可用作函数参数或返回值

    3.可存入变量的实体。

    ----------

    # 5 闭包(函数)

    闭包:嵌套函数,内部函数调用外部函数的变量

    ```python

    def outer():

        a = 1

        def inner():

            print(a)

    ```

    <br>

    ## 5.1 闭包的常用形式

    ```python

    def outer():

        a = 1

        def inner():

            print(a)

        return inner

    inn = outer()

    inn()

    ```

    执行结果

    ```

    1

    ```

    <br>

    ## 5.2 \__closure\__

    判断闭包函数的方法__closure__

    范例:

    ```python

    def outer():

        a = 1

        def inner():

            print(a)

        print(inner.__closure__)

    outer()

    print(outer.__closure__)

    ```

    执行结果:

    ```

    (<cell at 0x00000000026C02E8: int object at 0x000000005BB180C0>,)    # 输出的__closure__有cell元素 :是闭包函数

    None    # 输出的__closure__为None :不是闭包函数

    ```

    <br>

    ## 5.3 闭包函数的模拟案例

    不闭包的案例:

    ```python

    from urllib.request import urlopen

    ret = urlopen("https://www.baidu.com").read()

    print(ret)

    ```

    执行结果:

    ```

    b'<html>\r\n<head>\r\n\t<script>\r\n\t\tlocation.replace(location.href.replace("https://","http://"));\r\n\t</script>\r\n</head>\r\n<body>\r\n\t<noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></noscript>\r\n</body>\r\n</html>'

    ```

    <br>

    闭包案例:

    ```python

    from urllib.request import urlopen

    def get_url():

        url = "https://www.baidu.com"

        def get():

            ret = urlopen(url).read()

            print(ret)

        return get

    get_func = get_url()

    get_func()

    ```

    执行结果:

    ```

    b'<html>\r\n<head>\r\n\t<script>\r\n\t\tlocation.replace(location.href.replace("https://","http://"));\r\n\t</script>\r\n</head>\r\n<body>\r\n\t<noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></noscript>\r\n</body>\r\n</html>'

    ```

    相关文章

      网友评论

          本文标题:07_Python函数进阶_全栈开发学习笔记

          本文链接:https://www.haomeiwen.com/subject/xnqyaftx.html