发布于2023-01-21 10:58 阅读(1028) 评论(0) 点赞(28) 收藏(2)
目录
- 调用函数才会执行函数体代码. 不调用则不会执行.
- 函数体执行结束(或者遇到 return 语句), 则回到函数调用位置, 继续往下执行.
def test(): print("执行函数内部代码") print("执行函数内部代码") print("执行函数内部代码") print("1111") test() print("2222") test() print("3333")这个过程还可以使用 PyCharm 自带的调试器来观察:
- 点击行号右侧的空白, 可以在代码中插入 断点
- 右键, Debug, 可以按照调试模式执行代码. 每次执行到断点, 程序都会暂停下来.
- 使用 Step Into (F7) 功能可以逐行执行代码.
![]()
2.链式调用
编程演示:
# 判定是否是奇数 def isOdd(num): if num % 2 == 0: return False else: return True result = isOdd(10) print(result)实际上也可以简化写作 print(isOdd(10))
把一个函数的返回值 , 作为另一个函数的参数 , 这种操作称为 链式调用 .![]()
def isOdd(num): if num % 2 == 0: return False else: return True def add(x,y): return x+y print(isOdd(add(6,1)))这是一种比较常见的写法.
3.嵌套调用
函数内部还可以调用其他的函数 , 这个动作称为 " 嵌套调用 " .
def test(): print("执行函数内部代码") print("执行函数内部代码") print("执行函数内部代码")test 函数内部调用了 print 函数 , 这里就属于嵌套调用 .一个函数里面可以嵌套调用任意多个函数 .函数嵌套的过程是非常灵活的
def a(): print("函数 a") def b(): print("函数 b") a() def c(): print("函数 c") b() def d(): print("函数 d") c() d()如果把代码稍微调整, 打印结果则可能发生很大变化.
def a(): print("函数 a") def b(): a() print("函数 b") def c(): b() print("函数 c") def d(): c() print("函数 d") d()注意体会上述代码的执行顺序. 可以通过画图的方式来理解.![]()
![]()
函数之间的调用关系, 在 Python 中会使用一个特定的数据结构来表示, 称为 函数调用栈 . 每次函数调用, 都会在调用栈里新增一个元素, 称为 栈帧.
- 可以通过 PyCharm 调试器看到函数调用栈和栈帧.
- 在调试状态下, PyCharm 左下角一般就会显示出函数调用栈.
每个函数的局部变量 , 都包含在自己的栈帧中
def a(): num1 = 10 print("函数 a") def b(): num2 = 20 a() print("函数 b") def c(): num3 = 30 b() print("函数 c") def d(): num4 = 40 c() print("函数 d") d()
- 选择不同的栈帧, 就可以看到各自栈帧中的局部变量.
- 调用函数,则生成对应的栈帧;
- 函数结束,则对应的栈帧消亡(里面的局部变量也就消失了)
思考 : 上述代码 , a, b, c, d 函数中的局部变量名各不相同 . 如果变量名是相同的 , 比如都是 nums , 那么这四个函数中的 nums 是属于同一个变量 , 还是不同变量呢 ?![]()
def a(): nums = 10 print("函数 a") def b(): nums = 20 a() print("函数 b") def c(): nums = 30 b() print("函数 c") def d(): nums = 40 c() print("函数 d") d()
- 每个变量虽然同名,但其是不同变量。属于不同的函数作用域。
- 每个变量也是保存在各自的栈帧中的(每个栈帧也是保存在内存上),变量本质就是一块内存空间。
4.1 递归的概念
递归是嵌套调用 中的一种特殊情况 , 即一个函数嵌套调用自己 .代码示例 : 递归计算 5!
#写一个函数,求n的阶乘(n是正整数) def factor(n): if n == 1: return 1 return n * factor(n - 1) result = factor(5) print(result)![]()
上述代码中, 就属于典型的递归操作 . 在 factor 函数内部 , 又调用了 factor 自身 .![]()
def factor(n): result = 1 for i in range(1,n+1): result *= i return result print(factor(5))注意 : 递归代码务必要保证
- 存在递归结束条件. 比如 if n == 1 就是结束条件. 当 n 为 1 的时候, 递归就结束了.
- 每次递归的时候, 要保证函数的实参是逐渐逼近结束条件的.
如果上述条件不能满足 , 就会出现 " 无限递归 " . 这是一种典型的代码错误:
def factor(n): return n * factor(n - 1) result = factor(5) print(result)
- 如前面所描述, 函数调用时会在函数调用栈中记录每一层函数调用的信息.
- 但是函数调用栈的空间不是无限大的. 如果调用层数太多, 就会超出栈的最大范围, 导致出现问题.
![]()
Python 中的函数 , 可以给形参指定默认值 .带有默认值的参数 , 可以在调用的时候不传参 .代码示例 : 计算两个数字的和
def add(x, y, debug=False): if debug: print(f'调试信息: x={x}, y={y}') return x + y print(add(10, 20)) print(add(10, 20, True))此处 debug=False 即为参数默认值 . 当我们不指定第三个参数的时候 , 默认 debug 的取值即为 False.
带有默认值的参数需要放到没有默认值的参数的后面
def add(x, debug=False, y): if debug: print(f'调试信息: x={x}, y={y}') return x + y print(add(10, 20))![]()
多个带有默认参数的形参,这些 都得放在后面!
6. 关键字参数
在调用函数的时候 , 需要给函数指定实参 . 一般默认情况下是按照形参的顺序 , 来依次传递实参的 .但是我们也可以通过 关键字参数, 来调整这里的传参顺序, 显式指定当前实参传递给哪个形参.
def test(x, y): print(f'x = {x}') print(f'y = {y}') test(x=10, y=20) test(y=100, x=200)形如上述 test(x=10, y=20) 这样的操作 , 即为 关键字参数 .
- 位置参数和关键字参数还能混着使用,只不过混着用的时候要求位置参数在前,关键字参数在后。
- 关键字参数,一般搭配默认参数来使用的。
- 一个函数,可以提供很多的参数,来实现对这个函数的内部功能做出一些调整设定。为了降低调用者的使用成本,就可以把大部分参数设定为默认值。当调用者需要调整其中的一部分参数的时候,就可以搭配关键字参数来进行操作。
7. 小结
函数是编程语言中的一个核心语法机制 . Python 中的函数和大部分编程语言中的函数功能都是基本类似的.我们当下最关键要理解的主要就是三个点 :
- 函数的定义
- 函数的调用
- 函数的参数传递
我们在后续的编程中 , 会广泛的使用到函数 . 在练习的过程中再反复加深对于函数的理解 .
原文链接:https://blog.csdn.net/m0_57859086/article/details/128666241
作者:坚持才能胜利
链接:https://www.pythonheidong.com/blog/article/1885272/ed4730e7a33c02148404/
来源:python黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 python黑洞网 All Rights Reserved 版权所有,并保留所有权利。 京ICP备18063182号-1
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!