首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

第5.5节 函数递归、嵌套及样例

  • 23-09-22 19:01
  • 3546
  • 10213
blog.csdn.net

一、    函数递归及嵌套简介
1.    函数支持递归,递归就是函数可以在函数内调用自己,这种情况在C语言等语言就已经支持,不单独介绍;
2.    Python支持函数内再定义函数,这种方式称为函数嵌套。函数内的函数称为局部函数,其上层函数称为封闭函数:
1)    在默认情况下,局部函数对外部是隐藏的,局部函数只能在其封闭函数内有效;
2)    封闭函数也可以返回局部函数,以便程序在其他作用域中使用局部函数,此时返回的函数在调用方使用时就可以等同于普通函数一样使用;
3)    在局部函数中如果需要访问封闭函数的变量,需要使用nonlocal进行声明;
4)    局部函数大多数情况下可以与封闭函数使用两个函数实现,但局部函数在某些特定场景下使用可以简化程序的实现方式。相关内容在后面章节再介绍。
  
二、    函数其他的知识
1.    要判断某个对象是否为函数可调用,可使用内置函数callable,该函数参数为需要判断的对象如函数名,返回值为布尔值,为True就表示可调用;
2.    所有函数都是 function 对象,这意味着可以把函数本身赋值给变量,就像把整数、浮点数、列表、元组赋值给变量一样。举例:

  1. >>> def f(n1,n2,*n):
  2.     print('n1=',n1,',n2=',n2,',numbers=',n)
  3. >>> add=f
  4. >>>type(add)  #结果为:


3.    可将函数作为其他函数的形参,通过使用函数作为参数可以在调用函数时动态传入函数,实际上就可动态改变被调用函数的部分代码;
4.    Python 还支持使用函数作为其他函数的返回值;
5.    如果函数需要有多个返回值,则既可将多个值包装成容器的元素如列表之后返回,也可直接返回多个值。如果 函数直接返回多个值,Python 会自动将多个返回值封装成元组。六、    案例
1.    实现完整的可变参数的计算函数
该函数输入一串至少2个数字的不限数量的数字,然后调用对应的运算符进行连续运算(如连加、连减、连乘等),如:cal(‘+’,1,2,3) 、cal(‘*’,1,2,3,4)结果为24。不多说,直接上代码:

  1. >>> def cal2var(number1,number2,calmethod): #实现2个数的运算,第三个参数为运算符
  2.     if calmethod=='+':return  number1+number2;
  3.     elif  calmethod=='-':return  number1-number2;
  4.     elif  calmethod=='*':return  number1*number2;
  5.     elif  calmethod=='/':return  number1/number2;
  6.     else: raise ValueError('运算符必须是+-*/中的一个')
  7. >>> def cal(number1,number2,*numbers,calmethod='+'):
  8.  #实现n个数的运算,第1个和第2个参数必须有且是整数,后面还可以跟随不限量的多个整数,最后一个参数为运算符
  9.    print('number1=',number1,',number2=',number2,',numbers=',numbers,', calmethod=',calmethod) 
  10.    calmethod=calmethod.strip() #去掉运算符前后的空格
  11.    if len(calmethod)!=1: raise ValueError('运算符长度必须为1个字符') 
  12.    if '+-*/'.find(calmethod)==-1 :raise ValueError('运算符必须是+-*/中的一个') 
  13.    if not isinstance(number1,int): raise TypeError('第1个参数必须为整数') 
  14.    if not isinstance(number2,int): raise TypeError('第2个参数必须为整数') 
  15.    result=cal2var(number1,number2,calmethod)
  16.    for i,n in enumerate(numbers): #注意使用了enumerate函数,请参见前面的章节《几个与迭代相关的函数》内容
  17.        if  isinstance(n,int): #判断n是否为整数
  18.            result=cal2var(result,n,calmethod)
  19.        else:raise TypeError('第'+str(i+3)+'个参数必须为整数') 
  20.    return result
  21. >>> cal(1,2,3,4,5,6)
  22. number1= 1 ,number2= 2 ,numbers= (3, 4, 5, 6) , calmethod= +
  23. 21
  24. >>> cal(1,2,3,4,5,6,'*') #调用方式对吗?看结果
  25. number1= 1 ,number2= 2 ,numbers= (3, 4, 5, 6, '*') , calmethod= +
  26. Traceback (most recent call last):
  27.   File "", line 1, in <module>
  28.     cal(1,2,3,4,5,6,'*') #调用方式对吗?看结果
  29.   File "", line 12, in cal
  30.     else:raise TypeError('第'+str(i+3)+'个参数必须为整数')
  31. TypeError: 第7个参数必须为整数
  32. >>> cal(1,2,3,4,5,6,calmethod='*')
  33. number1= 1 ,number2= 2 ,numbers= (3, 4, 5, 6) , calmethod= *
  34. 720
  35. >>> cal(1,2,3,4,5,6,7)
  36. number1= 1 ,number2= 2 ,numbers= (3, 4, 5, 6, 7) , calmethod= +
  37. 28


    说明:
1)    上述实现先定义了函数cal2var,实现两个数的运算,因为cal函数中需要先实现第一个和第二个参数的运算,后面才是可变个数的参数参与运算,为了简化代码,就定义了cal2var,该函数的定义可以直接放到函数cal函数中作为局部函数,使用效果是相同的;
2)    看了cal函数的第一个print语句的输出就知道收集参数怎么使用;
3)    cal函数的calmethod有缺省值,因此放在最后,如果不使用缺省值,就可以放在第一个,这样后面调用时就不用关键字参数方式调用,本例特地这样使用,实际上由于收集参数后面必须是关键字参数的形式,因此这个缺省值没有用,主要是为了演示收集参数的实参和形参匹配过程;
4)    这个函数其实结合后面章节的动态执行方法有个更简单的实现方式,到时再演示。

2.    使用递归函数和局部函数再次实现上述案例

  1. def cal(number1,number2,*numbers,calmethod='+'): 
  2. #实现n个数的运算,第1个和第2个参数必须有且是整数,
  3. #后面还可以跟随不限量的多个整数,最后一个参数为运算符
  4.    def cal2var(number1,number2,calmethod): #局部函数实现2个数的运算,第三个参数为运算符
  5.        if calmethod=='+':return  number1+number2;
  6.        elif  calmethod=='-':return  number1-number2;
  7.        elif  calmethod=='*':return  number1*number2;
  8.        elif  calmethod=='/':return  number1/number2;
  9.        else: raise ValueError('运算符必须是+-*/中的一个') 
  10.    #由于递归调用传递参数时,将收集参数的数据(此时保存在元组内)作为参数传递,
  11.    #导致实际numbers可能是包含一个元组元素的元组,因此需要将这种情况的元素去掉一层元组
  12.    if len(numbers)==1:numbers=numbers[0]    
  13.    print('number1=',number1,',number2=',number2,',numbers=',numbers,'(len=',len(numbers),'), calmethod=',calmethod) 
  14.    calmethod=calmethod.strip() #去掉运算符前后的空格
  15.    if len(calmethod)!=1: raise ValueError('运算符长度必须为1个字符') 
  16.    if '+-*/'.find(calmethod)==-1 :raise ValueError('运算符必须是+-*/中的一个') 
  17.    if not isinstance(number1,int): raise TypeError('第1个参数必须为整数') 
  18.    if not isinstance(number2,int): raise TypeError('第2个参数必须为整数') 
  19.    result = cal2var(number1,number2,calmethod) 
  20.    if not len(numbers): return result
  21.    ops=list(numbers)
  22.    number=ops.pop(0)
  23.    return cal(result,number,tuple(ops),calmethod='+')  
  24.    return result


执行截图:
 
本节详细介绍了函数函数递归、函数嵌套以及函数的作用域相关内容,并进行了计算函数的实现。
老猿Python(http://iyenn.com/index/link?url=https://blog.csdn.net/LaoYuanPython)系列文章用于逐步介绍老猿学习Python后总结的学习经验,这些经验有助于没有接触过Python的程序员可以很容易地进入Python的世界。
欢迎大家批评指正,谢谢大家关注!

老猿Python
微信公众号
专注Python相关语言、图像音视频处理、AI
注:本文转载自blog.csdn.net的LaoYuanPython的文章"https://blog.csdn.net/LaoYuanPython/article/details/90670250"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2024 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top