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

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

 

  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. js事件委托target

    **看一看,瞧一瞧!** 话说要谈事件委托和target.那我们首先来看看什么是事件.话说什么是事件呢?一般的解释是比较重大.对一定的人群会产生一定影响的事情.而在JavaScript中就不是这样了, ...

  2. 02 layui 下载和搭建环境

    Layui官方网站 官方网站:https://www.layui.com/ 下载地址:https://res.layui.com/static/download/layui/layui-v2.5.5. ...

  3. [pdo_mysql.lo] Error 1 或者 [php_mysql.lo] Error 1

    make: *** [pdo_mysql.lo] Error 1 make: *** [php_mysql.lo] Error 1 这是因为这是因为在编译时需要 MySQL 的头的文件.而它按默认搜索 ...

  4. Druid未授权(弱口令)的一些利用方式

    Druid简介 1.Druid是阿里巴巴数据库事业部出品,为监控而生的数据库连接池. 2.Druid提供的监控功能,监控SQL的执行时间.监控Web URI的请求.Session监控. Druid可能 ...

  5. GPS北斗NTP校时服务器原理及功能介绍

    在科技的发展下GPS北斗NTP校时服务器也得到了广泛应用,比如工业.科研.航空航天.公共场所等领域都用到了GPS北斗NTP校时服务器,该时间服务器以卫星时间为基准授时准确,替代了传统钟表授时的单一和时 ...

  6. SQL中rownumber的用法

    1)一次排名: 语法:row_number() over(order by 字段 desc/asc):按照某个字段排名 1.1.查询语句: 1.2.查询结果:查询结果按照薪水进行排名 2)先分组后排名 ...

  7. VsCode从零开始配置一个属于自己的Vue开发环境

    vscode vue VsCode算是比较热门的一个代码编辑器了,全名Visual Studio Code下载地址:点我去下载插件众多,功能齐全,我在平常开发过程中都是用的它,整理了些自认好用的插件, ...

  8. Spring注解 - 组件的注册

    Spring Boot的出现极大的简化了我们的开发,让我们无需再写繁杂的配置文件,其正是利用了注解的便捷性,而Spring Boot又依赖于Spring,因此深入学习Spring的注解是十分必要的. ...

  9. Mybatis总结一之SQL标签方法

    ---恢复内容开始--- 定义:mapper.xml映射文件中定义了操作数据库的sql,并且提供了各种标签方法实现动态拼接sql.每个sql是一个statement,映射文件是mybatis的核心. ...

  10. Linux命令进阶篇-文件查看与查找

    上一篇的博客对于Linux如何在不同目录下跳转和查看目录下内容做出了总结,主要靠cd和ls,很常见也很实用.但是你看到目录下面那么多不同花花绿绿的文件,心里是不是痒痒,是不是想进去一探究竟,有办法! ...