zoukankan      html  css  js  c++  java
  • 函数对象、名称空间和作用域、闭包函数、装饰器

    一、函数对象:
      函数名就相当于变量名,把函数的内存地址当作一种变量值(一种数据类型)去使用
      在面向对象编程中,一切皆对象
      具体的体现:
        1.函数可以被引用
        2.函数可以作为函数的参数
        3.函数可以作为函数的返回值
        4.函数可以存储到容器类型中

    二、函数嵌套:
      1.嵌套定义
      def outer():
        def inner():
        pass
      2. 嵌套调用
      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

    三、名称空间和作用域
    名称空间:
      1.什么是名称空间:
        存放名字与值内存地址绑定关系的地方
        x=10
        x:10的内存地址

      2.为什么要有名称空间:

      3.如何用内存空间:
        内置名称空间:存放py解释器自带的函数名称
          parcharm解释器启动时创建,关闭解释器时销毁

        全局名称空间:文件级别的名称:除了内置名称和函数内名称,其余都是全局名称
          运行文件时创建,所有文件运行结束或者中途删除时销毁

        局部名称空间:函数内定义的名称
          调用函数时创建,函数执行完毕销毁

        查找名称顺序:
          1.查找名字的顺序是从当前位置往外查找
          2.名称空间的嵌套关系是在函数定义阶段就固定死的,与调用的位置没关系
          函数的作用域在定义时就固定了,与调用的位置没关系

        名称空间的加载顺序:
          内置>全局>局部
        名称空间的查找顺序:
          局部>全局>内置 (不能反着找)

    作用域:
      域指的是区域、范围
        即全局范围:全局存活 全局有效
        无论在任何位置都能看的到

      全局的名称空间和内置的名称空间 在使用上没什么区别
      局部的和全局的内置的 就有区别了 局部定义的只能在局部使用

      全局的 和 内置的可以划分为同一个范围
      global 表示的是全局范围 就是所谓的全局作用域

      局部的单独一个范围
      local 局部作用域

      globals() 查看全局作用域中的内容
      locals()查看局部作用域中的内容 (相对局部,站在什么位置看就是哪个局部,
        比如你在全局作用域中使用locals,看到的就是全局作用域的内容)


    四、闭包函数:

      1.什么是闭包函数
        闭函数:该函数一定是定义在函数内的函数
        包函数:该内部函数包含对外层函数作用域名字的引用

      2.为何要用闭包函数
        传值

      3.如何用
      为函数体传值的方案一:直接参数传
      def f():
        print(x)

      为函数体传值的方案二:闭包传值
      def outer(x):
        def f():
          print(x)
        return f

      f1 = outer(10)
      f2 = outer(11)

      f1()

      f2()

    五、装饰器
      1.什么是装饰器
        装饰器指的是为被装饰对象添加新功能的工具
        装饰器本身可以是任意可调用的对象
        被装饰对象本身也可以是任意可调用对象

      2.为何要用装饰器
        开放封闭原则:对修改封闭,对扩展开放

        装饰器的原则:
          1.不能修改被装饰对象的源代码
          2.不能修改被装饰对象的调用方式

        装饰器的目的:
          就是在遵循原则1和2的前提下,为被装饰对象添加新功能

      3.如何用

        1.源函数
        def index():
          time.sleep(1)
          print('welcome to index page')

        2.添加功能
        import time
        def index():
          time.sleep(1)
          print('welcome to index page')

        def outer(func):
          # func=最原始那个index的内存地址
          def wrapper(*args,**kwargs):
            start_time = time.time()
            res=func(*args,**kwargs):#最原始那个index的内存地址
            end_time = time.time()
            print('time is %s' %(end_time - start_time))
            return res
          return wrapper

        index=outer(index) #index=outer(最原始那个index的内存地址) index=wrapper的内存地址
        index() #wrapper的内存地址()
            # 偷梁换柱 用户并不知道

        3.语法糖
        import time
        def outer(func):
          # func=最原始那个index的内存地址
          def wrapper(*args,**kwargs):
            start_time = time.time()
            res=func(*args,**kwargs):#最原始那个index的内存地址
            end_time = time.time()
            print('time is %s' %(end_time - start_time))
            return res
            return wrapper

          @outer #index=outter(index)
          def index():
            time.sleep(1)
            print('welcome to index page')
          index()

        总结:

          要写一个装饰器,先定义一个新函数例如def inner():,写要添加的功能,写好之后打包。

          所谓打包其实有固定的套路,在新函数同级头下写return inner,在新函数同级头上写参数func=index(index为源函数名)

          定义一个外函数def outer():,将写好的新函数上下三行,统一缩进,打包进外函数内。就可以了

          使用语法糖,调用装饰器运行源函数即可。

  • 相关阅读:
    mysql数据库之多表查询
    mysql数据库之单表查询
    mysql数据库之表和库
    mysql数据库之windows版本
    mysql数据库之linux版本
    mysql数据库之mysql下载与设置
    python基础之逻辑题(3)
    python基础之逻辑题(2)
    python基础之逻辑题(1)
    spring boot统一异常处理
  • 原文地址:https://www.cnblogs.com/zhangxin-/p/10039309.html
Copyright © 2011-2022 走看看