十一天

今日内容

一、函数对象

  函数是第一类对象,即函数可以像变量一样使用
  特点:
        1、可以被引用
        2、可以当作参数传递
        3、返回值可以是函数
        4、可以当作容器类型的元素
  例:
        def foo():
            print('foo')

        def bar():
            print('bar')

        dic={
            'foo':foo,
            'bar':bar,
              }
        while True:
            choice=input('>>: ').strip()
            if choice in dic:
                dic[choice]()

二、函数嵌套

2.1函数嵌套的调用:

  例:
        def max2(x,y):
              if x > y:
                  return x
              else:
                  return y
        def max4(a,b,c,d):
              res1 = max2(a,b)
              res2 = max2(res1,c)
              res3 = max2(res2,d)
              return res3
        print(max4(11,22,33,44))

2.2函数嵌套的定义:

        def f1():
            def f2():
              def f3():
                  print("hello")
              f3()
            f2()
        f1()

三、名称空间与作用域

3.1名称空间

  1、什么是名称空间:
  存放名字的地方,有三种名称空间,py文件中一定会产生内置名称空间、全局名称空间,但不一定会产生局部内存空间
        (内置名称空间,全局名称空间,局部内存空间)

  2、名称空间的加载顺序:
        1、内置名称空间:启动python器就会首先加载内置名称空间
        2、全局名称空间:执行python文件的时候,基于代码内容,识别语法是加载全局名称空间
        3、局部名称空间:执行python文件的时候,识别语法中有函数的话才会加载局部内存空间

  3、名称空间的查找顺序:
        (内置(全局(内置)))
  需要注意的是:在全局无法查看局部的,在局部可以查看全局的,如下示例:
        max =1
        def f1():
            max=2
           def f2():
              max=3
              print(max)
           f2()
        f1()
       print(max)          #这时max的值会先从本层——》外层——》全局——》内置

3.2作用域

  1、什么是作用域:作用域即范围
        全局范围:内置名称空间和全局名称空间属于这个范围,特点:全局存活,全局有效
        局部范围:局部名称空间属于这个范围,特点:临时存活,局部有效
  
  2、作用域关系是在函数定义阶段就已经确定的,和函数的调用位置无关。
        例:x=1
           def f1():
            def f2():
              print(x)
            return f2
           x=100
          def f3(func):
              x=2
              func()
          x=10000
          f3(f1())       #这时打印出来的时10000,当函数内没有x时就会去全局找,而X这个变量在全局内最后定为10000
  3、阶级作用域的代表名字:
        LEGB 代表名字查找顺序: locals -> enclosing function -> globals -> __builtins__
        locals(当前函数本层) 是函数内的名字空间,包括局部变量和形参
        enclosing(本层函数与全局作用域之间的函数层) 外部嵌套函数的名字空间(闭包中常见)
        globals(全局层次) 全局变量,函数定义所在模块的名字空间
        builtins(内置层次) 内置模块的名字空间
  4、global与nonlocal关键字
        1、global例:
        x = 10
        y = 20
        def f1():
           x = 30
           y = 40
           def f2():
              global x,y     #声明本层用的X,Y是全局名称空间中的x,y
              print(x,y)
           f2()
        f1()        #这时打印的是10,20

        2、nonlocal例: 
        a = 10  # a1 当前模块全局变量
        def outer():
            a = 9 # a2 outer局部变量
            def inner():
                nonlocal a      #用于在函数内层中改变外层函数变量
                a = 8  # a3  既是inner局部变量,又是外层outer局部变量
                print(a)  # a3 8,在inner的局部作用域中找到了a3
            inner()  # inner()函数结束,a3作为外层变量(outer局部变量)被保留成为a2
            print(a)  # a2 8,在outer局部作用域中找到a2(在inner中被改变)
        outer()  # outer()函数结束,a2作为outer局部变量被释放
        print(a)  # a1 10,在当前模块全局作用域中找到了a1

四、闭包函数

4.1什么是闭包

  内部函数包含对外部作用域而非全局作用域的引用(一个函数把另一个函数封闭包起来)
  之前我们都是通过参数将外部的值传给函数,闭包提供了另外一种思路

4.2闭包的意义与应用

  1、闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,
  这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域
  2、应用
  例:
      def f1(x):
         def f2():
            print(x)
         return f2
      f = f1(111)
      f()
      f = f1(222)
      f()

五、装饰器

5.1为何要用装饰器

  开放封闭原则:对修改封闭,对扩展开放

5.2什么是装饰器

  装饰他人的器具,本身可以是任意可调用对象,被装饰者也可以是任意可调用对象。
  强调装饰器的原则:1 不修改被装饰对象的源代码 2 不修改被装饰对象的调用方式
  装饰器的目标:在遵循1和2的前提下,为被装饰对象添加上新功能
原文地址:https://www.cnblogs.com/kk942260238/p/14208422.html