程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长

+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2022-02(2)

2022-03(7)

<Python的函数(2)>——《Python》

发布于2023-01-21 10:58     阅读(1028)     评论(0)     点赞(28)     收藏(2)


目录

1.函数执行过程

2.链式调用

3.嵌套调用

4.函数递归

4.1 递归的概念

4.2 递归的优点

4.3 递归的缺点

5. 参数默认值

6. 关键字参数

7. 小结


1.函数执行过程

  • 调用函数才会执行函数体代码. 不调用则不会执行.
  • 函数体执行结束(或者遇到 return 语句), 则回到函数调用位置, 继续往下执行.
  1. def test():
  2. print("执行函数内部代码")
  3. print("执行函数内部代码")
  4. print("执行函数内部代码")
  5. print("1111")
  6. test()
  7. print("2222")
  8. test()
  9. print("3333")
这个过程还可以使用 PyCharm 自带的调试器来观察:
  • 点击行号右侧的空白, 可以在代码中插入 断点
  • 右键, Debug, 可以按照调试模式执行代码. 每次执行到断点, 程序都会暂停下来.
  • 使用 Step Into (F7) 功能可以逐行执行代码.

2.链式调用

编程演示:
  1. # 判定是否是奇数
  2. def isOdd(num):
  3. if num % 2 == 0:
  4. return False
  5. else:
  6. return True
  7. result = isOdd(10)
  8. print(result)
实际上也可以简化写作    print(isOdd(10))

 

把一个函数的返回值 , 作为另一个函数的参数 , 这种操作称为 链式调用 .
  1. def isOdd(num):
  2. if num % 2 == 0:
  3. return False
  4. else:
  5. return True
  6. def add(x,y):
  7. return x+y
  8. print(isOdd(add(6,1)))

这是一种比较常见的写法.

3.嵌套调用

函数内部还可以调用其他的函数 , 这个动作称为 " 嵌套调用 " .
  1. def test():
  2.    print("执行函数内部代码")
  3.    print("执行函数内部代码")
  4.    print("执行函数内部代码")
test 函数内部调用了 print 函数 , 这里就属于嵌套调用 .
一个函数里面可以嵌套调用任意多个函数 .
函数嵌套的过程是非常灵活的
  1. def a():
  2. print("函数 a")
  3. def b():
  4. print("函数 b")
  5. a()
  6. def c():
  7. print("函数 c")
  8. b()
  9. def d():
  10. print("函数 d")
  11. c()
  12. d()
如果把代码稍微调整, 打印结果则可能发生很大变化.
  1. def a():
  2. print("函数 a")
  3. def b():
  4. a()
  5. print("函数 b")
  6. def c():
  7. b()
  8. print("函数 c")
  9. def d():
  10. c()
  11. print("函数 d")
  12. d()
注意体会上述代码的执行顺序. 可以通过画图的方式来理解.

 函数之间的调用关系, Python 中会使用一个特定的数据结构来表示, 称为 函数调用栈 . 每次函数调用, 都会在调用栈里新增一个元素, 称为 栈帧.

  • 可以通过 PyCharm 调试器看到函数调用栈和栈帧.
  • 在调试状态下, PyCharm 左下角一般就会显示出函数调用栈.
每个函数的局部变量 , 都包含在自己的栈帧中
  1. def a():
  2.    num1 = 10
  3.    print("函数 a")
  4. def b():
  5.    num2 = 20
  6.    a()
  7.    print("函数 b")
  8. def c():
  9.    num3 = 30
  10.    b()
  11.    print("函数 c")
  12. def d():
  13.    num4 = 40
  14.    c()
  15.    print("函数 d")
  16. d()
  • 选择不同的栈帧, 就可以看到各自栈帧中的局部变量.
  • 调用函数,则生成对应的栈帧;
  • 函数结束,则对应的栈帧消亡(里面的局部变量也就消失了)
思考 : 上述代码 , a, b, c, d 函数中的局部变量名各不相同 . 如果变量名是相同的 , 比如都是 nums  , 那么这四个函数中的 nums 是属于同一个变量 , 还是不同变量呢 ?

  1. def a():
  2. nums = 10
  3. print("函数 a")
  4. def b():
  5. nums = 20
  6. a()
  7. print("函数 b")
  8. def c():
  9. nums = 30
  10. b()
  11. print("函数 c")
  12. def d():
  13. nums = 40
  14. c()
  15. print("函数 d")
  16. d()
  • 每个变量虽然同名,但其是不同变量。属于不同的函数作用域。
  • 每个变量也是保存在各自的栈帧中的(每个栈帧也是保存在内存上),变量本质就是一块内存空间。

4.函数递归

4.1 递归的概念

递归是嵌套调用 中的一种特殊情况 , 即一个函数嵌套调用自己 .
代码示例 : 递归计算 5!
  1. #写一个函数,求n的阶乘(n是正整数)
  2. def factor(n):
  3. if n == 1:
  4. return 1
  5. return n * factor(n - 1)
  6. result = factor(5)
  7. print(result)

上述代码中, 就属于典型的递归操作 . factor 函数内部 , 又调用了 factor 自身 .
  1. def factor(n):
  2. result = 1
  3. for i in range(1,n+1):
  4. result *= i
  5. return result
  6. print(factor(5))
注意 : 递归代码务必要保证
  • 存在递归结束条件. 比如 if n == 1 就是结束条件. n 1 的时候, 递归就结束了.
  • 每次递归的时候, 要保证函数的实参是逐渐逼近结束条件的.
如果上述条件不能满足 , 就会出现 " 无限递归 " . 这是一种典型的代码错误:
  1. def factor(n):
  2. return n * factor(n - 1)
  3. result = factor(5)
  4. print(result)

  • 如前面所描述, 函数调用时会在函数调用栈中记录每一层函数调用的信息.
  • 但是函数调用栈的空间不是无限大的. 如果调用层数太多, 就会超出栈的最大范围, 导致出现问题.

4.2 递归的优点

  • 递归类似于 "数学归纳法" , 明确初始条件, 和递推公式, 就可以解决一系列的问题.
  • 递归代码往往代码量非常少.

4.3 递归的缺点

  • 递归代码往往难以理解, 很容易超出掌控范围
  • 递归代码容易出现栈溢出的情况
  • 递归代码往往可以转换成等价的循环代码. 并且通常来说循环版本的代码执行效率要略高于递归版本.
实际开发的时候 , 使用递归要慎重 !

5. 参数默认值

Python 中的函数 , 可以给形参指定默认值 .
带有默认值的参数 , 可以在调用的时候不传参 .
代码示例 : 计算两个数字的和
  1. def add(x, y, debug=False):
  2.    if debug:
  3.        print(f'调试信息: x={x}, y={y}')
  4.    return x + y
  5. print(add(10, 20))
  6. print(add(10, 20, True))
此处 debug=False 即为参数默认值 . 当我们不指定第三个参数的时候 , 默认 debug 的取值即为 False.

带有默认值的参数需要放到没有默认值的参数的后面
  1. def add(x, debug=False, y):
  2.    if debug:
  3.        print(f'调试信息: x={x}, y={y}')
  4.    return x + y
  5. print(add(10, 20))

多个带有默认参数的形参,这些 都得放在后面!

6. 关键字参数

在调用函数的时候 , 需要给函数指定实参 . 一般默认情况下是按照形参的顺序 , 来依次传递实参的 .

但是我们也可以通过 关键字参数, 来调整这里的传参顺序, 显式指定当前实参传递给哪个形参.

  1. def test(x, y):
  2.    print(f'x = {x}')
  3.    print(f'y = {y}')
  4. test(x=10, y=20)
  5. test(y=100, x=200)
形如上述 test(x=10, y=20) 这样的操作 , 即为 关键字参数 .

 

  1. 位置参数和关键字参数还能混着使用,只不过混着用的时候要求位置参数在前,关键字参数在后。
  2. 关键字参数,一般搭配默认参数来使用的。
  3. 一个函数,可以提供很多的参数,来实现对这个函数的内部功能做出一些调整设定。为了降低调用者的使用成本,就可以把大部分参数设定为默认值。当调用者需要调整其中的一部分参数的时候,就可以搭配关键字参数来进行操作。

7. 小结

函数是编程语言中的一个核心语法机制 . Python 中的函数和大部分编程语言中的函数功能都是基本类似的.
我们当下最关键要理解的主要就是三个点 :
  • 函数的定义
  • 函数的调用
  • 函数的参数传递
我们在后续的编程中 , 会广泛的使用到函数 . 在练习的过程中再反复加深对于函数的理解 .

原文链接:https://blog.csdn.net/m0_57859086/article/details/128666241



所属网站分类: 技术文章 > 博客

作者:坚持才能胜利

链接:https://www.pythonheidong.com/blog/article/1885272/ed4730e7a33c02148404/

来源:python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

28 0
收藏该文
已收藏

评论内容:(最多支持255个字符)