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

news2024/11/21 1:32:17

目录

1.函数执行过程

2.链式调用

3.嵌套调用

4.函数递归

4.1 递归的概念

4.2 递归的优点

4.3 递归的缺点

5. 参数默认值

6. 关键字参数

7. 小结


1.函数执行过程

  • 调用函数才会执行函数体代码. 不调用则不会执行.
  • 函数体执行结束(或者遇到 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.函数递归

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)

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

4.2 递归的优点

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

4.3 递归的缺点

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

5. 参数默认值

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

 

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

7. 小结

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/159175.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

清晰解析浮点型在内存中的存储 浮点型如何取出 IEEE754 SME 精度丢失 C语言进阶

🐎作者的话 本文涵盖了浮点型在内存中的如何存储、如何取出、为何有精度丢失等知识点~ 跳跃式目录浮点型概括浮点数的存储bit位储存模型精度丢失浮点型的取出浮点数的取出实机演示浮点型概括 常见的浮点型数据有三种: 以科学计数法表示的:1…

php内核分析-fpm和df的问题思考

介绍 php中的disable_function是EG(ini_directives)来获得的,而phpinfo根据 EG(ini_directives) 中获取信息并打印。 然后通过zend_disable_function()函数去禁止,简单的说就是通过 func->handler ZEND_FN(display_disabled_function); 修改了handl…

ZigBee 3.0实战教程-Silicon Labs EFR32+EmberZnet-2-02:芯科的软件解决方案Gecko SDK

【源码、文档、软件、硬件、技术交流、技术支持,入口见文末】 【所有相关IDE、SDK和例程源码均可从群文件免费获取,免安装,解压即用】 持续更新中,欢迎关注! 虽然Silicon Labs是一家半导体公司,但是他们为…

手写spring13(xml自动扫描bean注册)

文章目录目标包扫描注解配置的使用占位符属性的填充设计类结构一、实现1、处理占位符配置——PropertyPlaceholderConfigurer2、定义Scope、Component拦截注解3、处理对象扫描装配——ClassPathBeanDefinitionScanner4、解析xml中调用扫描二、测试1、准备2、属性配置文件3、pri…

网络原理笔记一

文章目录1、局域网(LAN)2、广域网(WAN)3、网络通信基础1、IP地址2、端口号3、认识协议4、协议分层1、网络模型2、网络数据传输的基本流程1、局域网(LAN) 局域网全称:Local Area Network&#x…

【数据结构】顺序表深度剖析

目录 🛫前言🛫: 🚀一、线性表概述🚀: 🛰️二、顺序表🛰️: 1.概念及结构: 2.接口实现: ①.工程文件: ②.接口实现: ③.…

2023 铁人三项 CTF --- Misc wp

文章目录Misc一生壹世Misc手的必备技能套娃-1套娃-2套娃-3套娃-4套娃-5Misc 一生壹世 根据提示压缩包密码是谐音,所以猜测密码是1314,直接解压得到四个txt文件 然后用010分按照一生一世打开4个文件,发现每个文件的第一个字节拼起来是8950…

LeetCode题目笔记——1807. 替换字符串中的括号内容

文章目录题目描述题目难度——中等方法一:使用字典代码/Python代码/C总结题目描述 给你一个字符串 s ,它包含一些括号对,每个括号中包含一个 非空 的键。 比方说,字符串 “(name)is(age)yearsold” 中,有 两个 括号对…

什么是聚宽量化?

聚宽量化交易其实是通过编程将策略写成计算机可识别的代码,具体说可以是以python这门编程语言将与券商那边的平台搭建,例如用聚宽的向导式策略生成器就能很快的将股票交易接口翻译出来的策略,以便将平时需要查询的融资账户的持仓情况来编写代…

区块链将传统的产业运行逻辑,改造成以个体为主导的运行逻辑

新的产业之所以被成为新产业,其中一个很重要的原因在于,它的底层运行逻辑,正在发生一场深刻而又彻底的改变。然而,如果深入分析这种能够给产业的内在运行逻辑产生重塑和改变的,依然在于区块链本身。从某种意义上来讲&a…

YOLOv8 深度详解!一文看懂,快速上手

YOLOv8 是 ultralytics 公司在 2023 年 1月 10 号开源的 YOLOv5 的下一个重大更新版本,目前支持图像分类、物体检测和实例分割任务,在还没有开源时就收到了用户的广泛关注。 考虑到 YOLOv8 的优异性能,MMYOLO 也在第一时间组织了复现&#xf…

一篇文章搞定字符串的旋转问题(数组旋转问题)!

目录 前言 一.如何实现字符串的旋转? 1.用冒泡的思想实现 2.分别逆序左右再整体逆序来实现 二.如何快速判断一个字符串是否为另外一个字符串旋转之后的字符串? 1.相关库函数的简略学习 2.利用库函数快速实现判断 总结 博客主页:张栩睿…

数据结构基础知识(一)

1 数据结构的基本概念和算法 考点 数据结构基本概念算法 1.1 数据结构的基本概念 数据 数据是指所有能输入到计算机中的描述客观事物的符号,包括文本、声音、 图像、符号等。 数据元素 数据元素十数据的基本单位,也称节点或记录。 数据项 数据项…

【数仓】FLink+CK

1.项目分层 ODS:原始数据,包含日志和业务数据DWD:根据数据对象为单位进行分流。比如订单、页面访问等。DIM:维度数据DWM:对于部分数据对象进行进一步加工,比如独立访问、跳出行为,也可以和维度…

谷粒商城项目笔记之高级篇(三)

目录1.9.22 提交订单的问题1)、订单号显示、应付金额回显2)、提交订单消息回显3)、为了确保锁库存失败后,订单和订单项也能回滚,需要抛出异常1.9.23 创建库存上锁、解锁 业务交换机&队列1)、流程梳理2)、解锁库存实…

Vsftpd服务的部署及优化详解(图文)

目录 前言 实验环境 一、vsftpd的安装及启用 1、具体步骤 2、开启匿名用户访问功能并测试 二、vsftpd基本信息 三、匿名用户访问控制 四、本地用户访问控制 五、虚拟用户访问 1、建立虚拟用户访问 2、虚拟用户家目录的独立设定 3、用户配置独立 前言 vsftpd是“…

TapTap 算法平台的 Serverless 探索之路

分享人:陈欣昊,TapTap/IEM/AI平台负责人 摘要:本文主要介绍心动网络算法平台在Serverless上的实践。 《TapTap算法平台的 Serverless 探索之路》 Serverless 在构建应用上为我们节省了大量的运维与开发人力,在基本没投入基建人力…

(02)Cartographer源码无死角解析-(49) 2D点云扫描匹配→相关性暴力匹配1:SearchParameters

讲解关于slam一系列文章汇总链接:史上最全slam从零开始,针对于本栏目讲解(02)Cartographer源码无死角解析-链接如下: (02)Cartographer源码无死角解析- (00)目录_最新无死角讲解:https://blog.csdn.net/weixin_43013761/article/details/127350885 文末…

LeetCode分类刷题----链表篇

链表链表1.移除链表元素203.移除链表元素707.设计链表2.反转链表206.反转链表3.两两交换链表中的节点24.两两交换链表中的节点4.删除链表中的倒数第N个节点19.删除链表的倒数第N个节点5.链表相交07.链表相交6.环形链表141.环形链表142.环形链表II链表 1.移除链表元素 203.移除…

成功解决VMware安装操作系统出现分辨率的问题

文章目录问题重现问题原因问题解决方法一:拓展:1. 电脑分辨率:2. xrandr命令3. 查询后如果没有合适的分辨率解决方案参考资料问题重现 如下图: 在VMware16上安装ubuntu操作系统的时候,出现分辨率问题, 导致…