本文介绍:高阶函数,嵌套函数,以及由前面两个组成的装饰器

一、高阶函数:以下两种情况都是高阶函数

 

  1、将函数名当成参数传递给另外一个函数(作用:不修改被传递函数源代码就可以添加新功能):

  import time
  def a():
  time.sleep(1)
  print("This is A funciton...")
  # b函数相当于给a函数附加了一个计算时间的功能,但未修改a的源代码
  def b(func):
  print(func) # 打印func的内存地址
  start_time = time.time()
  func() # 调用a()
  end_time = time.time()
  print("a函数运行时间为:%s秒" % (end_time - start_time))
  b(a) # 将a函数当成一个变量传递给b

  2、将函数名当成返回值返回给另外一个函数(作用:不修改被传递函数调用方式就可以添加新功能):

  import time

  def a1():

  time.sleep(1)

      print("This is A1 funciton...")

  # b1函数相当于给a1函数附加了一个计算时间的功能,但未修改a的源代码,也未修改a1的调用方式

  def b1(func):
  start_time = time.time()
  func() # 调用a()
  end_time = time.time()
  print("a函数运行时间为:%s秒" % (end_time - start_time))
  return func
  a1 = b1(a1) # 将a1函数当成一个变量传递给b1
  a1() # 调用未改变a1的调用方式,依然是a1()调用,只不过此时的a1已经通过b1装饰过了。   
二、嵌套函数:在函数内部定义一个新的函数,注意:函数内部根据就近原则一层层往外寻找变量
    x = 0
    def grandpa():
      x = 1
      def dad():
    x = 2
        def son():           x = 3
              print(x)
    son()
    dad()
    grandpa()


三、装饰器:


  1、定义:在不修改函数代码和调用方式的前提下对该函数实现新功能的编程范式,形式上是利用高阶和嵌套函数的特性,高阶函数 + 嵌套函数 = 装饰器,
       所以装饰器本质上是一个未其他函数添加新功能的函数,而且不破坏原有代码。
  2、原则:
      a、不能修改被装饰函数的代码,此项可以防止修改以后对原来的程序逻辑造成影响
      b、不能修改被修饰函数的调用方式,比如原来是test()这样调用的,不能改成test(参数1)或者改名成test2()调用,这也是为了让原来的旧代码逻辑不会出现问题导致程序运行失败。
      c、综上所述,也就是说被装饰的函数感觉不到装饰器的存在,装饰器是透明的。   3、如何实现装饰器?
      a、函数也是一个变量,函数名是变量名,函数执行体就是具体的函数值,所以将函数名赋值给别的函数,在别的函数内部就可以直接使用该函数。
      b、单层装饰器:将函数名当成变量传递给另外一个函数,以达到装饰添加新功能的目的。
        def timer(func):
        def deco(*args,**kwargs): #这是一个嵌套函数,将*args和**kwargs可以允许外界传入任意个数的位置和关键词参数进来
        start_time = time.time()
        func(*args,**kwargs)
        stop_time = time.time()
        print("the func run time is %s" % (stop_time - start_time))         return deco         @timer #@timer标签就相当于这句话 test1 = time(test1) 将test1函数变量名传给装饰器
        def test1():
        time.sleep(1)
        print("This is test1")         @timer # test2 = time(test2)
        def test2(name,age):
        time.sleep(2)
        print("This is %s age:%d"%(name,age))         test1()
        test2("test2",23)   c、通过嵌套函数两层装饰器,可以让装饰器传递参数         def outside(arg_type):
        def inside(func):
        def deco(*args, **kwargs):
        return_value = ""
        if arg_type == "1":
        print("加载功能1")
        return_value = func(*args, **kwargs)
        print("加载功能2")
        elif arg_type == "2":
        print("加载功能3")
        return_value = func(*args, **kwargs)
        print("加载功能4")
        else:
        return_value = func(*args, **kwargs)
        print("加载功能5")
        return return_value # 这个返回值可以让被装饰的func函数的返回值传到外面
        return deco
        return inside         @outside(arg_type="1") # 在打标签装饰的同时,还可以传递参数给外层outside
        def test1():
          print("This is test1")
      return "test1"         @outside(arg_type="2")
        def test2():
        print("This is test2")
        return "test2"         @outside(arg_type="3")
        def test3(1,2):
        print("This is test3")
        return "test3"         # test1,test2和test3的的调用方式和其内部代码都未改变,但是通过装饰器却添加了新功能
        print(test1())
        print(test2())
        print(test3())

Python学习笔记:函数详解(下)的更多相关文章

  1. python基础之函数详解

    Python基础之函数详解 目录 Python基础之函数详解 一.函数的定义 二.函数的调用 三.函数返回值 四.函数的参数 4.1 位置参数 4.2 关键字参数 实参:位置实参和关键字参数的混合使用 ...

  2. Python内置函数详解

    置顶   内置函数详解 https://docs.python.org/3/library/functions.html?highlight=built#ascii https://docs.pyth ...

  3. python pandas字符串函数详解(转)

     pandas字符串函数详解(转)——原文连接见文章末尾 在使用pandas框架的DataFrame的过程中,如果需要处理一些字符串的特性,例如判断某列是否包含一些关键字,某列的字符长度是否小于3等等 ...

  4. Angular6 学习笔记——组件详解之模板语法

    angular6.x系列的学习笔记记录,仍在不断完善中,学习地址: https://www.angular.cn/guide/template-syntax http://www.ngfans.net ...

  5. Angular6 学习笔记——路由详解

    angular6.x系列的学习笔记记录,仍在不断完善中,学习地址: https://www.angular.cn/guide/template-syntax http://www.ngfans.net ...

  6. Angular6 学习笔记——组件详解之组件通讯

    angular6.x系列的学习笔记记录,仍在不断完善中,学习地址: https://www.angular.cn/guide/template-syntax http://www.ngfans.net ...

  7. JavaScript学习笔记-实例详解-类(二)

    实例详解-类(二)   //===给Object.prototype添加只读\不可枚举\不可配置的属性objectId(function(){ Object.defineProperty(Object ...

  8. JavaScript学习笔记-实例详解-类(一)

    实例详解-类(一): //每个javascript函数(除了bind())都自动拥有一个prototype对象// 在未添加属性或重写prototype对象之前,它只包含唯一一个不可枚举属性const ...

  9. Python学习笔记—函数

    函数 我们知道圆的面积计算公式为: S = πr2 当我们知道半径r的值时,就可以根据公式计算出面积.假设我们需要计算3个不同大小的圆的面积: r1 = 12.34 r2 = 9.08 r3 = 73 ...

  10. Android学习笔记-Dialog详解

    1.对话框的使用 1.1AlertDialog的显示 简单对话框以及监听的设置:重点掌握三个按钮(也就是三上单词): PositiveButton(确认按钮);NeutralButton(忽略按钮) ...

随机推荐

  1. Kubernetes-PersistentVolumeClaim(PVC)介绍

    1 PVC介绍   PVC是用户层面,作为对存储资源的需求申请,主要包括了存储空间大小.访问模式.PV的选择条件.存储类别等信息的设置. 2 PVC的参数详解 2.1 PVC的yaml模板 apiVe ...

  2. 网络|Trojan 网络代理服务搭建

    Trojan 网络代理服务搭建 前言 本文目的在于帮助相同困惑的网友,让使用更加简单. Trojan为Trojan-GFW开源的一款新思路网络代理软件, 前期准备 [x] 服务器:系统CentOS 7 ...

  3. Layabox 预制体prefab使用

    //腊鸭官方api不详细系列之ui预制体 // 创建预制体文件,随便拖一个场景中的预制体到 Assets的任意文件夹中,要规范的话则放在Prefab中 // 上一步操作完后就可以在文件夹中看到.pre ...

  4. iview2+ 表单密码验证

    <Form :model="formItem" v-model="formItem.id" ref="formItem" :label ...

  5. 量子计算机编程(二)——QPU基础函数

    第二部分主要是QPU的基础功能,第一部分就像是我们有了哪些基本的语句,第二部分就是我们能写一些简单基础的函数,一些小模块,第三部分就是他的应用了. 先来看一下一个简单量子应用的结构: 第一步,将量子态 ...

  6. 逐浪web无障碍与国际化以及全民族语言支持白皮书

    北京时间2019年5月10日,领先的门户网站与WEB内核服务厂商--上海Zoomla!逐浪CMS团队发布其年度重榜产品:逐浪CMS全民族语言与国际版,体验站点:http://demo2.z01.com ...

  7. 使用 Github Action 进行前端自动化发布

    前言 说起自动化,无论是在公司还是我们个人的项目中,都会用到或者编写一些工具来帮助我们去处理琐碎重复的工作,以节约时间提升效率,尤其是我们做前端开发会涉及诸如构建.部署.单元测试等这些开发工作流中重复 ...

  8. 如何安装vue-devtool调试工具

    1.从git上下载工具压缩包,github下载地址:https://github.com/vuejs/vue-devtools: 2.打开cmd,切换到下载的文件目录下:npm install---- ...

  9. 【Weiss】【第03章】双链表例程

    双链表因为多了个前向指针,需要考虑的特殊因素多了一倍 所以中间插入(这儿没写)和中间删除会比较复杂. 其它倒没什么特别的,代码如下. 测试代码 #include <iostream> #i ...

  10. JDBC封装-Java(新手)

    JDBC的封装,自己总结的自己总结的自己总结的 dao (代码分层)命名规范: 1.com.XXX.dao 存放dao相关的类型 例如 StudentDAOImpl 处理 数据库的链接 存取数据 2. ...