python函数基础:嵌套函数、作用域、匿名函数、高阶函数、递归函数
嵌套函数:
1. 函数内部可以再定义函数
2. 函数只有被调用之后才会执行
看如下代码:
age = 18 def func1():
age = 22
print(age) def func2():
age = 28 # 如果这个age没有被赋值,它会先向它的父级(func1)里面找,如果父级也没有就再向它的爷爷级(全局的age)找。 # 一层一层由内向外找
print(age)
func2() func1() # 输出结果:
#
#
注: 函数内部的变量都叫局部变量,只不过局部变量之间也有等级关系
#情景1:
age = 18 def func1(): def func2():
print(age)
age = 22 # age=22 依然是func1里面的变量
func2() #程序从上到下运行到这一步的时候 age已经在函数内被赋值为22 func1() #输出结果:
# #情景2:
age = 18 def func1(): def func2():
print(age)
func2() #程序由上到下运行到这一步时,由于func2中没有age,func2会向上一级找,找到了func1中的age=22,但由于变量需要先定义后使用(定义放在使用前面),所以程序会报错。例如情景3
age = 22 # age =22依然是函数func1里面的变量 func1() # 输出结果会报错。 #情景3:
age = 18 def func1(): def func2():
print(age2)
func2()
age2 = 22 func1() # 输出结果会报错。 #情景4:
age = 18 def func1():
global age #程序执行到这一步的时候,age已经被声明成了全局变量,并被赋值为18
def func2():
print(age) #执行到这一步的时候age直接调用age这个全局变量
func2()
age = 22 # 程序执行到这一步的时候age这个全局变量又被赋值成了22 func1()
print(age) # 输出结果:
#
# #情景5: age = 18 def func1():
global age #到这一步age被声明成全局变量,并且此时的值还是18
age = 22 # 到这一步时age又被重新赋值为22
def func2():
print(age)
func2() func1() #输出结果:
# #情景6:
age = 18 def func1():
global age #执行到这一步是age还是18
def func2():
print(age) #执行到这一步的时候age已经是22了
age = 22 # age这个全局变量 在func2调用之前又被改成了22
func2() func1() # 输出结果:
#
注:这几种情况用于分析,实际生产中很少用。
作用域:
在Python中一个函数的就是一个作用域,局部变量其实是放在它的作用域中
age = 18
def func1():
age = 22
def func2():
print(age) return func2 #func2没加括号,返回的是这个函数名 val= func1()
print(val) #打印的是函数名
val() #val就是func2, 此时会执行 # 输出结果:
# <function func1.<locals>.func2 at 0x0000009F6AEAB9D8>
# 22 #虽然是在外部执行,但依然是通过其定义域的关系去调用,所以不会是18.
代码定义完成后,作用域就已经生成。以后调用时会通过其定义域关系向上查找(不管这个函数名是在哪里被调用,只要一执行,它还是会回来它定义的地方向上去查找。)。
匿名函数:
# 普通函数:
def calc( x,y):
return x*y
# 匿名函数:
lambda x,y: x*y #声明一个匿名函数 (把多行语句变成一行)
调用:
func = lambda x,y: x*y
func(3,8)
匿名函数最复杂的也只能进行三元运算。
匿名函数通常跟其他的方法搭配使用,作用主要是节省代码量、如:
# 要求: 使range(10)里面的数各自跟自己相乘 data = list(range(10))
print(list(map(lambda x:x*x,data))) # 输出结果:
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] # map的用法: map(func, *iterables) --> map object
# 就是把iterables中的每一个值都进行一下前面的函数。
# list(map())的作用是让map的结果变成列表的样子
# iterables有:list,str,tuple,dict,file,xrange等
返回值:
# 匿名函数不需要return来返回值,表达式本身结果就是返回值。
高阶函数:
变量可以指向函数,函数的参数能够接收变量,一个函数可以接收另一个函数作为参数,这种函数就叫高阶函数。
另外,一个函数return了另外一个函数,这个也是高阶函数,如:
def func(x,y):
return abs,x,y # return 里面有abs, 是一个函数, 所以 func是高阶函数; 假如 return abs(x+y) 那func就不是高阶函数, 因为返回的是 abs(x+y),这是一个函数的结果, 不是函数。
res = func(3,-10)
print(res) # 输出结果:
# (<built-in function abs>, 3, -10) # func也是高阶函数
# abs是求绝对值的函数,用法:abs( 数字)
# 函数返回多个值的时候,是以元祖形式返回的
总结:
只需满足以下一个条件即为高阶函数:
1. 接收一个或多个函数作为输入
2. return返回另一个函数
递归函数:
如果一个函数在其内部调用了它自己,这样的函数就是递归函数。 如:让10除以2,直到为0.
a=
def calc(n):
n = int(n/)
print(n)
if n >:
calc(n) #在函数内部调用它自己,就会产生循环
calc(a) # 输出结果:
# 5
# 2
# 1
# 0 ## 而且,程序在结束退出的时候,是从内向外、一层一层逐渐结束的。
测试:
a=
def calc(n):
n = int(n/)
print(n)
if n >: #这一步的代码运行分析:第1次print的n是5,由于5>0,n直接进入calc(n),由于calc(n)调用了它自己,就没有再走下面的print(‘程序退出测试:’,n)这一步,而是又返回上面去进行n=int(n/2)这几步。n是2和1的时候也是同样的道理。
calc(n)
print('程序退出测试:',n) # 打印结果分析:最后一轮循环n的值是0,此时n==0不再进行calc(n),而是去运行下面的print(‘程序退出测试:’,n)这一步,此时最里面的这一层循环结束;然而上一步n==1时,程序是直接进入了if语句进行了calc(n),并没有进行下面的print语句,所以当最里面的n==0这层程序走完之后,n==1也要走完这个print语句。同理,n==2和5时也要依次走这个print语句。 calc(a) # 输出结果:
# 5
# 2
# 1
# 0
# 程序退出测试: 0
# 程序退出测试: 1
# 程序退出测试: 2
# 程序退出测试: 5
递归函数返回值:
在递归函数的外面得到返回值是最外层的函数return回来的,想要得到递归函数的返回值,需要在递归函数内部每次调用时都要有return值,只有这样最内层的return值才能通过一层层的return返回到最外层。它的书写方式是:
if 条件成立:
return 调用自己
else:
return 最里面的值
例如下面两个例子:
例子1: 100除以2三次,函数外部得到返回值。 a = 100
def func(n,count):
if count < 3:
return func(n/2,count+1)
else:
return n
result = func(a,0)
print(result) # 输出结果:
# 12.5 例子2: 求3的阶乘,函数外部得到返回值。 def f(n):
if n > 1:
return n*f(n-1)
else:
return n print(f(3)) # 输出结果:
#
下面用流程图说明它们的返回值是怎么得到的:
1. 3的阶乘:
2. 100除以2三次:
python函数基础:嵌套函数、作用域、匿名函数、高阶函数、递归函数的更多相关文章
- Python 进程线程协程 GIL 闭包 与高阶函数(五)
Python 进程线程协程 GIL 闭包 与高阶函数(五) 1 GIL线程全局锁 线程全局锁(Global Interpreter Lock),即Python为了保证线程安全而采取的独立线程运行的 ...
- Python小白学习之路(十四)—【作用域】【匿名函数】【编程方法论】【高阶函数】
吧啦吧啦内心戏 在没有具体学作用域之前,我在之前的学习笔记中就有提到 我开始以为是自己自创的词儿 没想到这个词早已经存在(手动捂脸) 真是个无知的小火锅(不知者无罪) 我发现自己最擅长做的事情,就是给 ...
- Python基础笔记:函数式编程:高阶函数、返回函数、匿名函数
高阶函数 高阶函数:一个函数可以接收另一个函数作为参数 或 一个函数可以返回一个函数作为返回值,这种函数称之为高阶函数. #函数 add 接收 f 函数作为参数 >>> def ad ...
- Python实用笔记 (12)函数式编程——高阶函数
函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数! Python对函数式编程提供部分支持.由于Python允许使用变量,因此,Python不是纯函数式编程语言. 变量 ...
- 【重温基础】JS中的常用高阶函数介绍
Ps. 晚上加班到快十点,回来赶紧整理整理这篇文章,今天老大给我推荐了一篇文章,我从写技术博客中收获到了什么?- J_Knight_,感受也是很多,自己也需要慢慢养成记录博客的习惯,即使起步艰难,难以 ...
- python开发基础04-函数、递归、匿名函数、高阶函数、装饰器
匿名函数 lamba lambda x,y,z=1:x+y+z 匿名就是没有名字 def func(x,y,z=1): return x+y+z 匿名 lambda x,y,z=1:x+y+z #与函 ...
- Python3学习之路~3.2 递归、函数式编程、高阶函数、匿名函数、嵌套函数
1 递归 在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数. def calc(n): print(n) if int(n / 2) == 0: return n r ...
- Python高阶函数和匿名函数
高阶函数:就是把函数当成参数传递的一种函数:例如 注解: 1.调用add函数,分别执行abs(-8)和abs(11),分别计算出他们的值 2.最后在做和运算 map()函数 python内置的一个高阶 ...
- Python小世界:匿名函数、高阶函数、推导式
前言 木子本人搞起Python已有多年,一直觉得什么都会,但是有时候实操起来,才觉得很多底层基础的知识都没有彻底的灵活掌握. 另外,网上关于Python基础知识的各种普及已有太多太多. 附上相关大神的 ...
- Python中的高阶函数与匿名函数
Python中的高阶函数与匿名函数 高阶函数 高阶函数就是把函数当做参数传递的一种函数.其与C#中的委托有点相似,个人认为. def add(x,y,f): return f( x)+ f( y) p ...
随机推荐
- Spring中bean的作用域与生命周期
在 Spring 中,那些组成应用程序的主体及由 Spring IOC 容器所管理的对象,被称之为 bean.简单地讲,bean 就是由 IOC 容器初始化.装配及管理的对象,除此之外,bean 就与 ...
- 使用mysqldump导出数据库(表)
mysqldump用来备份数据库或在不同数据库之间迁移数据,mydqldump的备份内容包括用来创建表和装载表的SQL语句. 一.mysqldump使用方法 (1).备份单个数据库或数据库中的部分表, ...
- SVN版本库的备份及迁移
备份某个版本库:打开控制台窗口 1.备份某个版本库: svnadmin dump myrepos > dumpfile //将指定的版本库导出成文件dumpfile eg:svnadmin du ...
- Python学习日记之忽略删除字符串空白
使用Python自带的函数strip可以剔除字符串开头.结尾.两端的空白 使用场景:用户输入验证 strip : 去除字符串两端的空白 rstrip : 去除字符串末尾(右端)的空白 lstrip : ...
- React组件的防呆机制(propTypes)
Prop验证 随着应用不断变大,为了保证组件被正确使用变得越来越重要.为此我们引入propsTypes.React.PropTypes提供很多验证器(valodator)来验证传入的数据的有效性.当向 ...
- Linux 学习(三)
Linux进程 1.进程 进程:可执行应用程序执行后产生的对应的进程,重量级:进程是由一个线程或多个线程构成: 线程:是计算机中的最小单位,轻量级(依赖和物理性是独立存在的).损耗较低 假设进程1是由 ...
- javascript按钮点击事件问题
今天弄了个小测试,结果发现了点问题. 就是有一个按钮的点击事件,页面加载时候没反应,只有F12启用开发人员工具的时候才有反应.后来反复测试发现名字起的不太合理 function onclick(){ ...
- day21-1 类的继承
目录 类的继承 什么是继承 为什么用继承 对象的继承 继承与抽象 继承的应用 对象属性查找顺序 类的继承 什么是继承 继承是一种创建新类的方式,新建的类可以继承一个或多个父类(python支持多继承) ...
- unittest自定义运行全量case or 运行指定的单个或多个case
import unittest import os from case.zufang.test_api_area_rentProlist import Zf1 case_path = os.path. ...
- cstring replace
//使用后将图纸名称存储到配置 换行符用^^替换 m_sTZMC.Replace(_T("\r\n"), _T("^^")); ini.SetValueOfKe ...