函数(下)——“Python”

各位CSDN的uu们你们好呀,今天小雅兰的内容是Python中的函数,其实距离上一篇Python的函数的时间很长了,小雅兰会通过这篇博客回忆起来曾经学过的知识,现在,让我们进入函数的世界吧

函数(上)——“Python”_认真学习的小雅兰.的博客-CSDN博客 

函数的链式调用和嵌套调用

局部变量和函数栈帧

函数递归

函数形参的默认值

函数的关键字参数

函数的链式调用和嵌套调用

链式调用

把一个函数的返回值, 作为另一个函数的参数, 这种操作称为链式调用。

# 判定是否是奇数
def isOdd(num):
   if num % 2 == 0:
     return False
   else:
     return True
result = isOdd(10)
print(result)

# 判定是否是奇数
def isOdd(num):
   if num % 2 == 0:
     return False
   else:
     return True

def add(x,y):
    return x+y

print(isOdd(add(5,5)))

 

 

链式调用的时候,也不要嵌套的层次太深!!!非常影响可读性!!!

 嵌套调用

函数内部还可以调用其他的函数, 这个动作称为 “嵌套调用” .

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 函数中的局部变量名各不相同. 如果变量名是相同的, 比如都是 num , 那么 这四个函数中的 num 是属于同一个变量, 还是不同变量呢?  

def a():
   num=10
   print("函数 a")

def b():
   num=20
   a()
   print("函数 b")

def c():
   num=30
   b()
   print("函数 c")

def d():
   num=40
   c()
   print("函数 d")

d()

 

函数递归

递归是嵌套调用中的一种特殊情况, 即一个函数嵌套调用自己.

下面,来看一个具体的例子:

写一个函数,来求n的阶乘(n是正整数)

 先使用循环的方式来求解:

def factor(n):
    result=1
    for i in range(1,n+1):
        result*=i
    return result
print(factor(5))

 

下面,来使用递归的方式来求解:

n!=n*(n-1)!

def factor(n):
  if n == 1:
    return 1
  return n * factor(n - 1)
result = factor(5)
print(result)

 

 

 

 

上述代码中, 就属于典型的递归操作. 在 factor 函数内部, 又调用了 factor 自身.  

 

注意:

  • 递归代码务必要保证存在递归结束条件. 比如 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))

 

函数的关键字参数

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

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

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) 这样的操作, 即为 关键字参数.

 

 小结

函数是编程语言中的一个核心语法机制. Python 中的函数和大部分编程语言中的函数功能都是基本类似的.

我们当下最关键要理解的主要就是三个点:

  • 函数的定义
  • 函数的调用
  • 函数的参数传递

我们在后续的编程中, 会广泛的使用到函数. 

好啦,小雅兰今天的内容就到这里啦,还要继续加油学习呀!!!

评论区走起来:人生苦短,我用Python!!!

 

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
社会演员多的头像社会演员多普通用户
上一篇 2023年4月25日
下一篇 2023年4月25日

相关推荐