递归调用、高阶函数、装饰器
一.递归调用
递归调用: 一个函数自己调用自己, 变成一个循环了,最多一个函数递归调用自己999,作用和运行循环是一样的,区别就是循环是没有次数限制的,递归调用最多999次,超过999次会报错:
递归的特性:
1、 必须有一个明确的结束条件 2、每次进入更深一层递归时,问题规模相比上次递归都应有所减少 3、递归效率不高,少用递归
eg:通过循环,函数自己调用自己
def test1():while True:num = int(input('please enter a number:'))if num%2==0:#判断输入的数字是不是偶数return True #如果是偶数的话,程序就退出了,返回trueprint('不是偶数请重新输入!')test1() #调用test
eg:通过递归,循环函数多次调用自己
def test1():num = int(input('please enter a number:'))if num%2==0:#判断输入的数字是不是偶数return True #如果是偶数的话,程序就退出了,返回trueprint('不是偶数请重新输入!')return test1()#如果不是偶数的话继续调用自己,输入值test1()#调用test
二.高阶函数
高阶函数: 如果一个函数的入参是一个函数名的话,这个函数就是高阶函数
函数即变量:虽然是一个函数,但是函数名是一个变量,变量存的是内存地址,指向的是函数体,加上括号了才是函数,那么给函数名重新赋值给一个变量的话,新变量与函数名是一样的,对新的变量名进行调用就和对原函数调用一样eg:函数即变量的例子
def hello(name):print(name) new_hello=hello #hello是一个普通的变量,将hello的值赋值给new_hello,代表的是内存地址hello('hello...')#hello()调用hello函数new_hello('newhello..') #new_hello()调用的跟hello()是一样的
eg:高阶函数的例子--入参是函数名就是高阶函数
def add(x,y,z): res=z(x)+z(y) #函数才可以用z()调用return res print(add('99','100',int))#int就是一个函数名
三.装饰器
装饰器:就是函数嵌套加高阶函数,像在打开淘宝购物的时候,哪些模块需要登录才可以操作的话,就需要用到装饰器了。
装饰器作用,在不改变原有函数调用方式入参的情况下,给函数添加新功能,偷偷给函数加上新功能,但是不改变原来的函数
1. 函数里可以嵌套定义函数:但是函数不管在哪都是调用了才会执行,不调用是不会执行的
Eg:函数有内嵌函数,但是没有调用
def warpper():print('我在外面')def deco():print('我在里面')def hh():print('我在最里面') warpper()
返回结果:
我在外面
Eg:函数有内嵌函数,且有调用
def warpper():print('我在外面')def deco():print('我在里面')def hh():print('我在最里面')hh()deco() warpper()
返回结果:
我在里面zhang
VVVzhang
2.函数作用域,是就近原则,函数里有的话就先取自己,自己没有的话,就找父级的,父级没有再往外找,查找的原则是从里往外找 # 函数只有被调用才会执行,执行顺序按照函数调用的顺序
Eg: 函数作用域例子
name='luoluo'def warpper():print('我在外面%s'%name)def deco():name = 'MLing'print('我在里面%s'%name)def hh():print('我在最里面%s'%name)hh()deco() warpper()
3. 装饰器:函数效率不高,查找哪个原因导致效率慢装饰器作用,在不改变原有函数调用方式入参的情况下,给函数添加新功能,偷偷给函数加上新功能,但是不改变原来的函数
Eg:下面的例子获取函数的运行时间--改变原来的调用方式了 原调用方式run()---后来调用方式run_time(run)
import timedef run():print('run..')time.sleep(1)def run_time(func):start_time=time.time()func() #run传给func,func里面就是函数里的代码体,指向run函数里的两行代码end_time=time.time()print("run函数运行是",end_time-start_time) run_time(run)#run代表变量,指向的函数体里的代码,
Eg: 下面的这个函数,其实就是就是返回了一个函数名而已deco函数没调用
import timedef timer(func): #定义一个函数,入参是函数名def deco(): #再定义个函数,将要给函数新加的功能写进去start_time = time.time()func()end_time = time.time()print("run函数运行是", end_time - start_time)return deco #返回这个定义的函数体def run():print('run..')time.sleep(1) timer(run) #这样调用是没有结果的,因为deco没有调用,所以timer只返回了一个deco函数名r=timer(run)#其实r=decor()#其实就是deco(),是给原来的run函数增加了新功能之后的,但是有改变原来的调用方式,由run()变为了r()
装饰器的处理逻辑:
1、调用timer函数的时候,要传入一个方法名func,timer函数在函数内部定义了一个函数叫做deco 2、deco函数内有新功能,且在函数内部调用了timer里面传入的方法-func() 3、当调timer函数时,返回的是函数体deco,可用函数deco已经把方法-func()要实现的功能都完成了,这个直接运行deco就实现了新功能 4、既然函数deco实现了新功能,函数即变量,给deco重新赋值就行,run=deco的话,run就有了新功能
Eg:装饰器例子1—与上面的例子类似def run():print('run..')time.sleep(1)import timedef run_time(func):def deco():start_time=time.time()func()end_time=time.time()print("run函数运行是",end_time-start_time)return deco#返回这个定义的函数体 run=run_time(run) run()
Eg:装饰器例子2---@run_time=run=run_time(run)import timedef run_time(func):#固定格式def deco():#固定格式start_time=time.time()func()end_time=time.time()print("run函数运行是",end_time-start_time)return deco#固定格式 @run_time #哪个函数用,就放在哪个函数前面def run():print('run..')time.sleep(1) run()
注意:疑惑的是为什么要内嵌一个函数,就是为了不改变原来函数的调用方式,返回的是函数体,其实就是把新功能封装在了deco这个函数体里面了def run():print('run..')time.sleep(1)import timedef run_time(func):def deco():start_time=time.time()func()end_time=time.time()print("run函数运行是",end_time-start_time)return deco run=run_time(run) print('返回的deco是什么',run)
返回结果:
返回的deco是什么 <function run_time.<locals>.deco at 0x000000F442D8E730>
注意:当函数有入参的话,就需要接收传入函数的参数—下面例子是比较完美的装饰器了,有没有入参都可以
import time,os,sysdef timer(func):def deco(*args,**kwargs):#*args,**kwargs用来接收传入函数的参数start_time = time.time()res = func(*args,**kwargs)#获取返回值 end_time = time.time()print('runtime',end_time-start_time) return res return deco
@timerdef run2(name):print(name)time.sleep(0.5) run2('niuhanyang')
转载于:https://www.cnblogs.com/MLing/p/7020040.html
递归调用、高阶函数、装饰器相关推荐
- 【函数】一篇文章带你看懂控制流、递归、高阶函数
目录 控制流 条件语句 迭代语句 示例:质因数分解 递归 示例:阶乘 示例:斐波那契数列 示例:判断奇偶数 高阶函数 lambda 表达式 设计函数 示例:累加计算 示例:柯里化 Lab 1: Fun ...
- 尾递归调用 高阶函数 map filter reduce
#!/user/bin/env python# -*- coding:utf-8 -*-# 1.函数递归调用,函数返回值如果是另一个函数,而不是一个确切值,返回的则是这个函数的地址,需要我们加上()后 ...
- Python中的装饰器、迭代器、生成器、推导式、匿名函数和高阶函数
文章目录 装饰器 迭代器 生成器 推导式 匿名函数 高阶函数 装饰器 闭包 介绍装饰器前先了解一下闭包,在Python中,一切皆对象(Object),函数(Function)也不例外,也是一个普通的对 ...
- 初学者python笔记(装饰器、高阶函数、闭包)
一个函数被定义完成后,甚至程序发布后,后期可能需要添加某些功能,但是我们不可能每次都去修改原函数的代码,这时候装饰器就可以上场了,本篇文章将会用一个个可实现的代码,由浅入深.循序渐进得阐述装饰器的强大 ...
- Kotlin高阶函数
1.高阶函数定义 函数的参数接收的是另一个函数,或者返回值是另一个函数类型,我们把这类函数称为高阶函数 2.函数类型 字符串的类型用String表示,整型用Int表示,那么函数的类型呢? // 参数b ...
- 【廖雪峰Python学习笔记】高阶函数
Higher-order function 高阶函数 映射 过滤算法 排序算法 高阶函数 变量可指向函数 >>> abs # 函数 <built-in function abs ...
- c++绝对值函数_Python自带自定义高阶函数实战
一.概述 高阶函数,就是一个函数可以接收另一个函数作为参数的函数,或者接受一个或多个函数作为输入并输出一个函数的函数.scala与之类似. 二.自带常用高阶函数 1.map #map(f, Itera ...
- Kotlin小知识之高阶函数
文章目录 高阶函数 定义高阶函数 函数类型 高阶函数示例 内联函数 内联函数的作用 内联函数的用法 noinline与crossinline 高阶函数 定义高阶函数 高阶函数和Lambda的关系是密不 ...
- 【kotlin】高阶函数详解
文章目录 定义高阶函数 内联函数的作用 高级函数的应用 简化SharedPreferences 的用法 简化 ContentValues 的用法 定义高阶函数 如果一个函数接收另一个函数作为参数,或者 ...
- Kotlin 使用高阶函数实现回调
lambda 和 高阶函数 之前学习了 lambda 和高阶函数,然后在 android 开发中对 onClick 事件进行监听是一个很常用的功能,kotlin 的常规实现如下: rootView.s ...
最新文章
- 2021年大数据Flink(十一):流批一体API Source
- 创建自己的人脸识别系统
- Oracle Golden Gate 系列十五 -- GG Trails 说明
- 萌新发问:MyBatis日志到底是如何做到兼容所有常用日志框架的?
- Vmware中安装Ubuntu的步骤
- JavaScript语法详解(三)
- 如何解决Ubuntu 12.04(64位)系统在virtualbox环境下无法开机自动挂载共享目录的问题
- 在vscode中用tsc编译ts文件的时候报错,tsc : 无法加载文件,因为在此系统上禁止运行脚本;SecurityError
- CodeSmith实用技巧(八):生成的代码输出到文件中
- ldr和adr在使用标号表达式作为操作数的区别
- python编码规范与命名规范
- getComputedStyle与currentStyle获取样式(style/class)
- php10天速成培训,十天学会php之第九天
- Day04 dom详解及js事件
- mx350显卡天梯图_2019.8月CPU和显卡性能天梯图
- 玩客云安装mysql_玩客云的使用经验总结
- CCIE一年后的心语-------寄WOLF实验室的兄弟
- 微信小程序 生成UUID
- 武林外传之勇夺金掌柜 【安卓游戏】
- 等值连接、自然连接和内连接之间的区别
热门文章
- Node.js webpack babel
- python iterableiterator
- python __xxxitem__
- CentOS7系统服务管理systemctl
- Oracle数据库链路
- web平台安装程序 无效的uri_1、Linux云计算系列CentOS7网络服务web搭建
- js 按给定数组的顺序给数组排序_JavaScript中如何如何给数组以及数组对象根据value值进行排序。...
- 102份深圳炒房材料曝光 网友举报千人炒房大会
- vSAN其实很简单-Quickstart是一件很炫的东西
- 阿里云物联网平台 > 设备接入 > 使用开放协议自主接入 > MQTT协议接入 >