【python】—— 函数详解

前言:

  • 本期,我们将要讲解的是有关python中函数的相关知识!!!

目录

(一)函数是什么

(二)语法格式

(三)函数参数

(四)函数返回值

(五)变量作用域

(六)函数执行过程

(七)链式调用

(八)嵌套调用

(九)函数递归

(十)参数默认值

(十一)关键字参数

总结


(一)函数是什么

编程中的函数和数学中的函数有一定的相似之处

数学上的函数, 比如 y = sin x , x 取不同的值, y 就会得到不同的结果.

  • 编程中的函数, 是一段 可以被重复使用的代码片段 .
     

接下来,我以几个简单的代码为例带大家认识函数:

  •  ① 求 1 - 100 的和
     

  •  ② 2. 求 300 - 400 的和

 ③ 求 1 - 1000 的和

 可以发现, 这几组代码基本是相似的, 只有一点点差异. 可以把重复代码提取出来, 做成一个函数

实际开发中, 复制粘贴是一种不太好的策略. 实际开发的重复代码可能存在几十份甚至上百份.

一旦这个重复代码需要被修改, 那就得改几十次, 非常不便于维护

💨 代码示例: 求 数列 的和, 使用函数

【说明】 

  1. 在给出的代码中,有一个函数定义 calcSum(beg, end) ,该函数计算从 beg 到 end 范围内所有整数的总和,并将结果打印出来;
  2. 可以明显看到, 重复的代码已经被消除了
     

(二)语法格式

函数是用于封装可重用代码块的基本编程概念。在Python中,函数可以接收输入参数并返回一个或多个值。函数的定义使用 def 关键字,后跟函数名、参数列表和冒号,然后是函数体。

  • 创建函数/定义函数
     

def 函数名(形参列表):
        函数体
        return 返回值

  • 调用函数/使用函数
     
函数名(实参列表)
返回值 = 函数名(实参列表)
// 不考虑返回值
// 考虑返回值

  • 函数定义并不会执行函数体内容, 必须要调用才会执行. 调用几次就会执行几次
     

  •  函数必须先定义, 再使用


(三)函数参数
 

在函数定义的时候, 可以在 ( ) 中指定 "形式参数" (简称 形参), 然后在调用的时候, 由调用者把 "实际参数"(简称 实参) 传递进去.
 

这样就可以做到一份函数, 针对不同的数据进行计算处理.

考虑前面的代码案例:
 

def calcSum(beg, end):sum = 0for i in range(beg, end + 1):sum += iprint(sum)# 调用函数
calcSum(1, 100)
calcSum(300, 400)
calcSum(1, 1000)

【说明】

  1. 上面的代码中, beg, end 就是函数的形参. 1, 100 / 300, 400 就是函数的实参;
  2. 在执行 sum(1, 100) 的时候, 就相当于 beg = 1, end = 100 , 然后在函数内部就可以针对 1-100 进行运算.
  3. 在执行 sum(300, 400) 的时候, 就相当于 beg = 300, end = 400 , 然后在函数内部就可以针对300-400 进行运算.

实参和形参之间的关系, 就像签合同一样.
 

 甲方, 乙方 这就相当于形参.张三, 李四 就是实参

def 签合同(甲方, 乙方):合同内容....
签合同('张三', '李四')
签合同('张三', '王五')
签合同('张三', '赵六')

注意:

  1. 一个函数可以有一个形参, 也可以有多个形参, 也可以没有形参.
  2. 一个函数的形参有几个, 那么传递实参的时候也得传几个. 保证个数要匹配.
     

  •  和 C++ / Java 不同, Python 是动态类型的编程语言, 函数的形参不必指定参数类型. 换句话说, 一个函数可以支持多种不同类型的参数


(四)函数返回值

函数的参数可以视为是函数的 " 输入 ", 则函数的返回值 , 就可以视为是函数的 " 输出 " .
  1. 此处的 "输入", "输出" 是更广义的输入输出, 不是单纯指通过控制台输入输出.
  2. 我们可以把函数想象成一个 "工厂". 工厂需要买入原材料, 进行加工, 并生产出产品.
  3. 函数的参数就是原材料, 函数的返回值就是生产出的产品.
我们可以看下列代码:
def calcSum(begin ,end):sum = 0for i in range (begin ,end+1):sum += iprint(sum)calcSum(1,100)

【解释说嘛】

  1. 这段代码是一个计算从begin到end之间所有整数的和的函数。它使用一个for循环来遍历从begin到end之间的整数,并将它们累加到变量sum中。最后,通过print函数打印出累加结果。
  2. 在这个例子中,调用calcSum(1, 100)会计算从1到100的所有整数的和,并将结果打印出来。

上述代码可以转换成 下述这样:

def calcSum(begin ,end):sum = 0for i in range (begin ,end+1):sum += ireturn sumresult = calcSum(1,100)
print(result)

【解释说明】

这两个代码的区别就在于 , 前者直接在函数内部进行了打印, 后者则使用 return 语句把结果返回给函数调用者, 再由调用者负责打印 .
  1. 我们一般倾向于第二种写法.
  2. 实际开发中我们的一个通常的编程原则, "逻辑和用户交互分离". 而第一种写法的函数中, 既包含 了计算逻辑, 又包含了和用户交互(打印到控制台上). 这种写法是不太好的, 如果后续我们需要的是把计算结果保存到文件中, 或者通过网络发送, 或者展示到图形化界面里, 那么第一种写法的函数,就难以胜任了.
  3. 而第二种写法则专注于做计算逻辑, 不负责和用户交互. 那么就很容易把这个逻辑搭配不同的用户交互代码, 来实现不同的效果.

接下来,我在举几个例子带大家去瞧瞧:

  • 一个函数中可以有多个 return 语句:
# 判定是否是奇数
def isOdd(num):if num % 2 ==0:return Falseelse:return Trueresult = isOdd(10)
print(result)
  • 执行到 return 语句, 函数就会立即执行结束, 回到调用位置:
# 判定是否是奇数
def isOdd(num):if num % 2 ==0:return Falsereturn Trueresult = isOdd(19)
print(result)

【解释说明】 

  • 如果 num 是偶数, 则进入 if 之后, 就会触发 return False , 也就不会继续执行 return True 

  •  一个函数是可以一次返回多个返回值的. 使用 , 来分割多个返回值:
def getpoint():x=10y=20return x, ya ,b = getpoint()
  • 如果只想关注其中的部分返回值, 可以使用 _ 来忽略不想要的返回值.
def getPoint():x = 10y = 20return x, y
_, b = getPoint()

 


(五)变量作用域

在Python中,变量的作用域指的是变量在程序中的可见性和访问范围。

Python中有以下几种变量作用域:

  • 全局作用域:在函数外部定义的变量拥有全局作用域,可以在整个程序中的任何位置进行访问。这些变量通常被称为全局变量。

  • 局部作用域:在函数内部定义的变量拥有局部作用域,只能在函数内部进行访问。这些变量通常被称为局部变量,它们的作用域限定在函数内部。

接下来,通过代码给大家演示一下:

x = 10  # 全局变量def func():y = 5  # 局部变量,只在函数内部可见print("x inside func:", x)  # 可以访问全局变量xprint("y inside func:", y)func()print("x outside func:", x)  # 可以在函数外部访问全局变量x
print("y outside func:", y)  # 抛出 NameError,无法访问局部变量y

输出展示:

【解释说明】

  • 在这个例子中,函数func()内部定义了一个局部变量y,它只能在函数内部访问。而全局变量x可以在函数内外访问。

  • 嵌套作用域:当函数嵌套定义时,内部函数可以访问外部函数的变量,这些被内部函数访问的变量位于嵌套作用域中。

 代码展示:

def outer():x = 10  # 外部函数的局部变量def inner():nonlocal x  # 声明x来自于嵌套作用域x += 5    # 修改外部函数的局部变量xprint("x inside inner:", x)  # 打印修改后的xinner()print("x inside outer:", x)  # 打印外部函数的xouter()

输出展示:

【解释说明】

  • 在这个例子中,内部函数inner()可以访问外部函数outer()的局部变量x,通过使用nonlocal关键字可以在内部函数中修改外部函数的局部变量。

  • 内置作用域:Python中有一些内置的名称,如printlen等,它们存在于内置作用域中,可以在任何地方直接访问。

 代码展示:

import mathdef calculate_circle_area(radius):area = math.pi * radius ** 2  # 内置函数math.pi处于内置作用域return arearesult = calculate_circle_area(10)
print("Circle area:", result)

输出展示:

【解释说明】

  • 在这个例子中,math.pi是内置函数math提供的常量,它属于内置作用域,可以在任何地方直接访问和使用。

 


Python的变量作用域遵循以下规则:

  • 当在函数内部访问一个变量时,首先会在局部作用域中查找该变量,如果找到则使用局部作用域中的值:

代码展示:

x = 20
def test():x = 10print(f'函数内部 x = {x}')test()

输出展示:


  • 如果函数内部尝试访问的变量在局部不存在, 就会尝试去全局作用域中查找

代码展示:

x = 20
def test():print(f'x = {x}')
test()

输出展示:

 


  • 如果需要在函数内部修改全局变量,可以使用global关键字将变量声明为全局变量。例如:

代码展示:

x = 10  # 全局变量
def modify_global():global x  # 声明x为全局变量x += 5    # 在函数内部修改全局变量modify_global()
print(x)  

输出展示:

【解释说明】

  • 需要注意的是,在函数内部修改全局变量可能会导致代码逻辑复杂化,建议谨慎使用全局变量,尽可能使用参数传递和返回值来实现数据的传递。

  • if / while / for 等语句块不会影响到变量作用域
换而言之 , if / while / for 中定义的变量 , 在语句外面也可以正常使用:
for i in range(1, 10):print(f'函数内部 i = {i}')print(f'函数外部 i = {i}')

输出展示:

【解释说明】

  1. 需要注意的是,在 Python 中,循环变量 i 在循环结束后仍然存在并保留其最后一次迭代的值;
  2. 因此,在打印 "函数外部 i" 的第二个输出中,i 的值将是循环结束时的最后一个值,即 9。

(六)函数执行过程

调用函数才会执行函数体代码 . 不调用则不会执行 .
函数体执行结束 ( 或者遇到 return 语句 ), 则回到函数调用位置 , 继续往下执行 .

def test():print("执行函数内部代码")print("执行函数内部代码")print("执行函数内部代码")
print("1111")
test()
print("2222")
test()
print("3333")

输出展示:

这个过程还可以使用 PyCharm 自带的调试器来观察.
  • 点击行号右侧的空白, 可以在代码中插入 断点
  • 右键, Debug, 可以按照调试模式执行代码. 每次执行到断点, 程序都会暂停下来.
  • 使用 Step Into (F7) 功能可以逐行执行代码.

(七)链式调用

 我们以上述判断奇偶数的代码为例:

  • 上述代码时这样写的
# 判定是否是奇数
def isOdd(num):if num % 2 == 0:return Falseelse:return Trueresult = isOdd(10)
print(result)
  • 实际上也可以简化写作

把一个函数的返回值 , 作为另一个函数的参数 , 这种操作称为 链式调用( 这是一种比较常见的写法 .
【小结】
  1. 通过链式调用,我们可以在一行代码中依次执行多个操作,使代码更简洁、易读;
  2. 但需要注意的是,链式调用并不适用于所有情况,有时候将每个方法的返回值存储到变量中可能更加清晰明了。

(八)嵌套调用

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

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()
输出展示:

  • 注意体会上述代码的执行顺序. 可以通过画图的方式来理解.
函数之间的调用关系 , Python 中会使用一个特定的数据结构来表示 , 称为 函数调用栈 . 每次函数调用 , 都会在调用栈里新增一个元素, 称为 栈帧 .
  • 可以通过 PyCharm 调试器看到函数调用栈和栈帧.
  • 在调试状态下, PyCharm 左下角一般就会显示出函数调用栈.

 

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

def a():num1 = 10print("函数 a")
def b():num2 = 20a()print("函数 b")
def c():num3 = 30b()print("函数 c")
def d():num4 = 40c()print("函数 d")d()
  • 选择不同的栈帧, 就可以看到各自栈帧中的局部变量.


(九)函数递归

嵌套调用是指在一个函数或方法的执行过程中,又调用了另一个函数或方法。嵌套调用可以允许我们在一个函数内部调用另一个函数来实现更复杂的功能。

下面是一个简单的示例来说明嵌套调用的概念:

def Func(n):if n <= 0:print("Countdown complete!")else:print(n)Func(n - 1)  # 在函数内部调用自身Func(5)
  • 上述代码中, 就属于典型的递归操作. 在Func函数内部, 又调用了Func自身。
注意 : 递归代码务必要保证
  1. 存在递归结束条件. 比如 if n <= 0 就是结束条件. n  0 的时候, 递归就结束了.
  2. 每次递归的时候, 要保证函数的实参是逐渐逼近结束条件的
如果上述条件不能满足 , 就会出现 " 无限递归 " . 这是一种典型的代码错误:
def Func(n):print(n)Func(n - 1)  # 在函数内部调用自身Func(5)

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

递归的优点
  1. 递归类似于 "数学归纳法" , 明确初始条件, 和递推公式, 就可以解决一系列的问题.
  2. 递归代码往往代码量非常少.
递归的缺点
  1. 递归代码往往难以理解, 很容易超出掌控范围
  2. 递归代码容易出现栈溢出的情况
  3. 递归代码往往可以转换成等价的循环代码. 并且通常来说循环版本的代码执行效率要略高于递归版

【小结】

  • 函数递归在解决特定问题时可以提供简洁的解决方案,但需要小心使用,确保递归停止条件的正确性和递归调用的终止条件。


(十)参数默认值

参数默认值是指在定义函数时为函数参数设置的默认值。当调用函数时,如果没有为相应的参数提供值,那么该参数将使用默认值作为其值。参数默认值可以使函数在不同场景中更加灵活和易用。

以下是一个示例来说明参数默认值的使用:

def add(x, y, debug=False):if debug:print(f'调试信息: x={x}, y={y}')return x + yprint(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 + yprint(add(10, 20))

输出展示:


(十一)关键字参数

在调用函数的时候 , 需要给函数指定实参 . 一般默认情况下是按照形参的顺序 , 来依次传递实参的 .
但是我们也可以通过 关键字参数 , 来调整这里的传参顺序 , 显式指定当前实参传递给哪个形参 .

【解释说明】

  1. 形如上述 test(x=10, y=20) 这样的操作, 即为 关键字参数;
  2. 关键字参数允许我们在函数调用时不需要按照参数的位置顺序进行传递,而是使用参数名来明确指定每个参数的值;

总结

到此,关于python中函数的讲解便到此结束了。接下来,简单的回顾总结一下!!!

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

以上便是本期的全部内容,感谢大家的观看与支持!!!

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

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

相关文章

webpack实战:某网站JS逆向分析

文章目录 1. 写在前面2. 抓包分析3. 扣加密代码 1. 写在前面 好的逆向能够帮助我们了解加密实现&#xff0c;然后根据加密方式&#xff08;md5,base64,res,des,rsa…)还原加密算法的过程。可以看看我之前的这篇文章&#xff1a;快速定位查找加密方式特征与技巧 目标站点&#…

什么是rem单位和em单位?它们有什么区别?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ rem 和 em 单位⭐ rem 单位&#xff08;Root Em&#xff09;⭐ em 单位⭐ 区别总结⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入…

java八股文面试[多线程]——newWorkStealingPool

newWorkStealingPool是什么&#xff1f; newWorkStealingPool简单翻译是任务窃取线程池。 newWorkStealingPool 是Java8添加的线程池。和别的4种不同&#xff0c;它用的是ForkJoinPool。 使用ForkJoinPool的好处是&#xff0c;把1个任务拆分成多个“小任务”&#xff0c;把这…

UDP 广播

一、UDP 通信图解 UDP通信、本地套接字_呵呵哒(&#xffe3;▽&#xffe3;)"的博客-CSDN博客https://blog.csdn.net/weixin_41987016/article/details/132523536?spm1001.2014.3001.5501 #include <sys/types.h> #include <sys/socket > ssize_t sendto(in…

hadoop学习:mapreduce的wordcount时候,继承mapper没有对应的mapreduce的包

踩坑描述&#xff1a;在学习 hadoop 的时候使用hadoop 下的 mapreduce&#xff0c;却发现没有 mapreduce。 第一反应就是去看看 maven 的路径对不对 settings——》搜索框搜索 maven 检查一下 Maven 路径对不对 OK 这里是对的 那么是不是依赖下载失败导致 mapreduce 没下下…

MySQL总复习

目录 登录 显示数据库 创建数据库 删除数据库 使用数据库 创建表 添加数据表数据 查询表 添加数据表多条数据 查询表中某数据 增insert 删delete 改update 查select ​ where like ​编辑 范围查找 order by 聚合函数 count max min sum avg g…

风险评估

风险评估概念 风险评估是一种系统性的方法&#xff0c;用于识别、评估和量化潜在的风险和威胁&#xff0c;以便组织或个人能够采取适当的措施来管理和减轻这些风险。 风险评估的目的 风险评估要素关系 技术评估和管理评估 风险评估分析原理 风险评估服务 风险评估实施流程

提升生产效率,降低运维成本:纺织业物联网网关应用

在众多物联网技术应用中纺织业正逐渐崭露头角。物联网技术通过无线连接纺织设备、PLC、传感器&#xff0c;实现了纺织厂的生产数据信息的远程监控和数据采集、远程管理&#xff0c;为企业提供了更高效、智能的生产方式。智联物联小编在本文中将重点介绍纺织业物联网的应用与通讯…

【USRP】调制解调系列7:GMSK、MSK、基于labview的实现

MSK 在数字调制中&#xff0c;最小频移键控&#xff08;Minimum-Shift Keying&#xff0c;缩写&#xff1a;MSK&#xff09;是一种连续相位的频移键控方式&#xff0c;在1950年代末和1960年代产生。与偏移四相相移键控&#xff08;OQPSK&#xff09;类似&#xff0c;MSK同样将…

Arcface部署应用实战

1、概述 人脸识别的一个比较常用的网络arcface&#xff0c;依赖于其特殊设计的loss函数&#xff0c;使得模型在训练的时候能够实现类间距离增大&#xff0c;类内的距离不断减小&#xff0c;最终使得所训练的backbone能够获取鉴别性很高的特征&#xff0c;便于人脸识别。 本文…

Mac 安装php多版本,brew安装php8.0

因为需要我要在mac上装两个php版本&#xff0c;先前我已经装过php7.4,下面我们逐步安装php8.0 开始安装8.0&#xff1a; 直接运行安装 brew install php8.0 遇到问题怀疑是仓库太老了&#xff0c;更新一下homebrew ,重新安装 brew update 安装成功了,不过看了下版本好像不能正…

PowerBuilder连接SQLITE3

PowerBuilder,一个古老的IDE,打算陆续发些相关的,也许还有人需要,内容可能涉及其他作者,但基本都是基于本人实践整理,如涉及归属,请联系. SQLite,轻型数据库,相对与PowerBuilder来说是个新事务,故发数来,以供参考. PB中使用OLE Microsoft OLE DB方式进行连接,如下 // Profile…

【jsvue】联合gtp仿写一个简单的vue框架,以此深度学习JavaScript

用 gtp 学习 Vue 生命周期的原理 lifecycle.js function Vue(options) {// 将选项保存到实例的 $options 属性中this.$options options;// 若存在 beforeCreate 钩子函数&#xff0c;则调用之if (typeof options.beforeCreate function) {options.beforeCreate.call(this);…

ChatGPT Prompting开发实战(四)

一、chaining prompts应用解析及输出文本的设定 由于输入和输出都是字符串形式的自然语言&#xff0c;为了方便输入和输出信息与系统设定使用的JSON格式之间进行转换&#xff0c;接下来定义从输入字符串转为JSON list的方法&#xff1a; 定义从JSON list转为输出字符串的方法&…

[华为云云服务器评测] Unbutnu添加SSH Key、编译启动Springboot项目

系列文章目录 第一章 [linux实战] 华为云耀云服务器L实例 Java、node环境配置 第二章 [linux实战] Unbutnu添加SSH Key、启动Springboot项目 文章目录 系列文章目录前言一、任务拆解二、配置git,添加SSH Key2.1、登录远程主机2.2、配置git用户名和邮箱2.3、生成SSH key2.4、查…

第 361 场 LeetCode 周赛题解

A 统计对称整数的数目 枚举 x x x class Solution { public:int countSymmetricIntegers(int low, int high) {int res 0;for (int i low; i < high; i) {string s to_string(i);if (s.size() & 1)continue;int s1 0, s2 0;for (int k 0; k < s.size(); k)if …

钡铼R40边缘计算网关与华为云合作,促进物联网传感器数据共享与应用

场景说明 微型气象是不可预测的&#xff0c;基本上不能通过人工手段来分析其变化&#xff0c;因此必须运用新技术&#xff0c;对气象进行实时监测&#xff0c;以便采取相应的措施来避免或解决事故的发生。而常规气象环境数据采集容易造成数据损失、人力成本高、数据安全性差、…

升级iOS17后iPhone无法连接App Store怎么办?

最近很多用户反馈&#xff0c;升级最新iOS 17系统后打开App Store提示"无法连接"&#xff0c;无法正常打开下载APP。 为什么升级后无法连接到App Store&#xff1f;可能是以下问题导致&#xff1a; 1.网络问题导致App Store无法正常打开 2.网络设置问题 3.App Sto…

项目介绍:《Online ChatRoom》网页聊天室 — Spring Boot、MyBatis、MySQL和WebSocket的奇妙融合

在当今数字化社会&#xff0c;即时通讯已成为人们生活中不可或缺的一部分。为了满足这一需求&#xff0c;我开发了一个名为"WeTalk"的聊天室项目&#xff0c;该项目基于Spring Boot、MyBatis、MySQL和WebSocket技术&#xff0c;为用户提供了一个实时交流的平台。在本…

渗透测试漏洞原理之---【任意文件包含漏洞】

文章目录 1、文件包含概述1.1 文件包含语句1.1.1、相关配置 1.2、动态包含1.2.1、示例代码1.2.2、本地文件包含1.2.3、远程文件包含 1.3、漏洞原理1.3.1、特点 2、文件包含攻防2.1、利用方法2.1.1、包含图片木马2.1.2、读取敏感文件2.1.3、读取PHP文件源码2.1.4、执行PHP命令2.…