函数(下)——“Python”

简介: 函数(下)——“Python”

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


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


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


局部变量和函数栈帧


函数递归


函数形参的默认值


函数的关键字参数


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


链式调用


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

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

30ffe08f658842e29d1740ae16b6e312.png

# 判定是否是奇数
def isOdd(num):
   if num % 2 == 0:
     return False
   else:
     return True
def add(x,y):
    return x+y
print(isOdd(add(5,5)))

a0e9347df133494ab474a9a08918dc89.png

3f47632225094c6a99be4b511ba61263.png

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

嵌套调用

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

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()

2eb4aa69f9734aaa8654c41dcb900155.png

b519245ec85e473890e142f10988db99.png

如果把代码稍微调整, 打印结果则可能发生很大变化.

def a():
   print("函数 a")
def b():
   a()
   print("函数 b")
def c():
   b()
   print("函数 c")
def d():
   c()
   print("函数 d")
d()

66d3608f90674347b868a47be3b8a2c9.png

7ea8240f2caa4610a224126f96123dfa.png

上述过程仍然可以使用调试器来分析!!!


 局部变量和函数栈帧

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

可以通过 PyCharm 调试器看到函数调用栈和栈帧.

在调试状态下, PyCharm 左下角一般就会显示出函数调用栈.

6dd8881ac8344fa195462a2b50a52d19.png

69234fa4e47740aaae150eae3cc073a4.png

每个函数的局部变量, 都包含在自己的栈帧中

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()

选择不同的栈帧, 就可以看到各自栈帧中的局部变量.

d7bc4aefa5ee4381b1ffcd778e7c67ec.png

思考: 上述代码, 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()

5f31966f9490469db890b5e952c30796.png

函数递归

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

258e68c9c80c4b4bb5ee042626fdd87c.png

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

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

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

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

5dbefee8111440228725cc015472c3a9.png下面,来使用递归的方式来求解:

n!=n*(n-1)!

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

4989767255c64256846f94b7bd210bbc.png

dc1385d8a3234ff3a2e6926962f78ab3.png

0d6871212672400c90e1deaf6a3f9a7c.png

ad480c6f19bc42569f7a595073a31c06.png

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

598508b96d314d6799b08a1fc9f008a4.png

5a7c67d55c5d4cae8469fb2a9f1aaf74.png

注意:

  • 递归代码务必要保证存在递归结束条件. 比如 if n == 1 就是结束条件. 当 n 为 1 的时候, 递归就结束了.
  • 每次递归的时候, 要保证函数的实参是逐渐逼近结束条件的.

如果上述条件不能满足, 就会出现 "无限递归" . 这是一种典型的代码错误.

91105ac5c4fb45359d7ad5e83bb084d8.png

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

92f4cd8b576d47359947fd5895d4a738.png

如前面所描述, 函数调用时会在函数调用栈中记录每一层函数调用的信息.


但是函数调用栈的空间不是无限大的. 如果调用层数太多, 就会超出栈的最大范围, 导致出现问题.


递归的优点


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

递归代码往往代码量非常少.

递归的缺点


递归代码往往难以理解, 很容易超出掌控范围

递归代码容易出现栈溢出的情况

递归代码往往可以转换成等价的循环代码. 并且通常来说循环版本的代码执行效率要略高于递归版本.

实际开发的时候, 使用递归要慎重!

90dd40856f4844e9815dc86f9cffc0e5.png

a90f783f26154d2cbef24c630ae55d86.png

函数形参的默认值

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))

a5b9187ad0e8476788d68330304139a6.png

此处 debug=False 即为参数默认值. 当我们不指定第三个参数的时候, 默认 debug 的取值即为 False.  

c837d31a911640f398910e3b9a6458d6.png

41f61b559595496fb944a71bf004dcf9.png

带有默认值的参数需要放到没有默认值的参数的后面

def add(x, debug=False, y):
    if debug:
        print(f'调试信息: x={x}, y={y}')
    return x + y
print(add(10, 20))

e7379c5823a74902b036f09e98c5a7b9.png

0de8b0997c8f4eb591ad36172f2120c4.png

函数的关键字参数

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

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

def test(x, y):
   print(f'x = {x}')
   print(f'y = {y}')
test(x=10, y=20)
test(y=100, x=200)

24f48a26266a4776b72bb89cbc867b67.png

形如上述 test(x=10, y=20) 这样的操作, 即为 关键字参数.

f976991f1c5744bfa0093246f636223c.png

bb2c1b4762d54f9aa203a7b376a8f8b2.png

小结


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


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


函数的定义

函数的调用

函数的参数传递

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


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


cd506569c03344748ed1bb9fb25bf621.jpg

相关文章
|
2月前
|
搜索推荐 Python
利用Python内置函数实现的冒泡排序算法
在上述代码中,`bubble_sort` 函数接受一个列表 `arr` 作为输入。通过两层循环,外层循环控制排序的轮数,内层循环用于比较相邻的元素并进行交换。如果前一个元素大于后一个元素,就将它们交换位置。
146 67
|
3天前
|
Python
[oeasy]python057_如何删除print函数_dunder_builtins_系统内建模块
本文介绍了如何删除Python中的`print`函数,并探讨了系统内建模块`__builtins__`的作用。主要内容包括: 1. **回忆上次内容**:上次提到使用下划线避免命名冲突。 2. **双下划线变量**:解释了双下划线(如`__name__`、`__doc__`、`__builtins__`)是系统定义的标识符,具有特殊含义。
18 3
|
7天前
|
JSON 监控 安全
深入理解 Python 的 eval() 函数与空全局字典 {}
`eval()` 函数在 Python 中能将字符串解析为代码并执行,但伴随安全风险,尤其在处理不受信任的输入时。传递空全局字典 {} 可限制其访问内置对象,但仍存隐患。建议通过限制函数和变量、使用沙箱环境、避免复杂表达式、验证输入等提高安全性。更推荐使用 `ast.literal_eval()`、自定义解析器或 JSON 解析等替代方案,以确保代码安全性和可靠性。
22 2
|
1月前
|
Python
Python中的函数是**一种命名的代码块,用于执行特定任务或计算
Python中的函数是**一种命名的代码块,用于执行特定任务或计算
50 18
|
26天前
|
数据可视化 DataX Python
Seaborn 教程-绘图函数
Seaborn 教程-绘图函数
54 8
|
1月前
|
Python
Python中的函数
Python中的函数
45 8
|
2月前
|
监控 测试技术 数据库
Python中的装饰器:解锁函数增强的魔法####
本文深入探讨了Python语言中一个既强大又灵活的特性——装饰器(Decorator),它以一种优雅的方式实现了函数功能的扩展与增强。不同于传统的代码复用机制,装饰器通过高阶函数的形式,为开发者提供了在不修改原函数源代码的前提下,动态添加新功能的能力。我们将从装饰器的基本概念入手,逐步解析其工作原理,并通过一系列实例展示如何利用装饰器进行日志记录、性能测试、事务处理等常见任务,最终揭示装饰器在提升代码可读性、维护性和功能性方面的独特价值。 ####
|
2月前
|
Python
Python中的`range`函数与负增长
在Python中,`range`函数用于生成整数序列,支持正向和负向增长。本文详细介绍了如何使用`range`生成负增长的整数序列,并提供了多个实际应用示例,如反向遍历列表、生成倒计时和计算递减等差数列的和。通过这些示例,读者可以更好地掌握`range`函数的使用方法。
57 5
|
2月前
|
测试技术 数据安全/隐私保护 Python
探索Python中的装饰器:简化和增强你的函数
【10月更文挑战第24天】在Python编程的海洋中,装饰器是那把可以令你的代码更简洁、更强大的魔法棒。它们不仅能够扩展函数的功能,还能保持代码的整洁性。本文将带你深入了解装饰器的概念、实现方式以及如何通过它们来提升你的代码质量。让我们一起揭开装饰器的神秘面纱,学习如何用它们来打造更加优雅和高效的代码。
|
2月前
|
中间件 Docker Python
【Azure Function】FTP上传了Python Function文件后,无法在门户页面加载函数的问题
通过FTP上传Python Function至Azure云后,出现函数列表无法加载的问题。经排查,发现是由于`requirements.txt`中的依赖包未被正确安装。解决方法为:在本地安装依赖包到`.python_packages/lib/site-packages`目录,再将该目录内容上传至云上的`wwwroot`目录,并重启应用。最终成功加载函数列表。