当前位置: 首页 > news >正文

【玩转python】入门篇day14-函数

1、函数的定义

函数通过def定义,包括函数名、参数、返回值

# 定义函数
def test(a,b):  # a,b表示形式参数print(a + b)#函数体(具体的功能)return a*b  #返回值# 函数调用
test(12,43)  # 12和43表示实际参数,在调用函数时,会替换形式参数a,b

下面这个展示了稍微复杂的函数嵌套,执行test()的时候test函数中顺序先执行test1,输出‘9999’,然后接着执行print("12345"),输出‘12345’


def test():test1()print("12345")
# test()  在此处调用,会报错,因为代码顺序执行,test1()在这里还没有定义
def test1():print("9999")test()

2、函数中的参数

(1)先看下面例子,引入形参和实参的概念

# 封装一个函数,传入两个数字,输出较大的一个数字
def get_max(num1,num2):  # num1和num2是形式参数if num1 > num2:print('较大的数字是:',num1)else:print('较大的数字是:',num2)get_max(32,47)   # 32和47是实际参数

上述代码中,定义了一个名为get_max的函数,传递两个形参num1,num2,函数体是比较num1和num2,执行代码get_max(32,47),这里的32和47就是实参,我们可以在任何地方调用get_max函数,传递想要的实参,函数体根据传递的参数计算出结果。

  1. 调用函数的时候,必须以正确的顺序传参一一对应,比如上面的传惨num1等于32,num2等于47,实参的数量和形参的数量保持一致
  2. 在函数中,形参的名字和实参的名字可以一样.(本质上是在程序中开辟了不同的内存空间)

(2)关键字参数

上面我们说了,实参和形参是数量相等一一对应的,比如上面的函数def get_max(num1,num2),接收的是num1和num2两个参数,然后调用的时候get_max(12,2),这样参数一一对应,12传递给num1,2传递给num2,但是能不能不按照顺序呢,答案是可以的,就是利用我们的关键字参数,看代码

get_max(num2 = 2,num1 = 12)

按照代码所示的关键字参数传递方式直接指明了num2 = 2,num1 = 12

(3)默认参数(在定义函数的时候,给形式参数直接赋值)

def he(num1,num2 = 23):  # num2 = 23表示默认参数print('num1和num2两个数字的和是:',num1 + num2)# 未使用默认参数
# he(10,50)  #输出 60
# 使用了默认参数
# he(82)  #输出 105

从上面的代码我们可以总结一下,默认参数的意义在于给形参设置一个默认值,你可以调用的时候重新传递覆盖,也可以就用默认值,比如上面的调用he(10,50),10传递给num1,50覆盖默认值23,计算和输出60,假如我们调用 he(82),这个时候82传递给num1,num2就用默认值32,计算和输出105,使用默认值有几个地方要注意:

  1. 前面我们说形参和实参数量要一致,那为什么这里可以这样调用 he(82),只是传递一个参数82,其实这个很好理解,因为形参num2设置了默认值,相当于82传递给num1,num2有默认值,所以实参可以不用传

  2. 把默认参数放在参数列表的前面会报错,比如下面代码会报错

def cha(num1 = 23,num2): #这里报错了,默认值参数设置要放在后面print('num1和num2两个数字的差是:',num1 - num2)

根据第一点的讲解我们也能较好的理解为什么默人参数前置会报错,因为你想假如按照cha(num1 = 23,num2)这样定义函数合法,那么当我们调用he(82)时这个82就会顺序传递到num1上,那num2参数就没有值了,所以这样不合理,反过来就不会存在这个问题

(4)不定长参数(可变参数):可以处理比声明时更多的参数. *args **kwargs

  • *args: 用来接收多个位置参数,得到的是元组. 是arguments的简写
  • **kwargs: 用来接收多个关键字参数,得到的是一个字典. 是 keyword arguments的简写
def fn(*args):print(args)# fn(12,34)   # (12, 34)
# fn(87,45,67)  # (87, 45, 67)
# fn(82,48,246,52)  # (82, 48, 246, 52)
注意: 当 args 和普通参数放在一起的时候,需要将args放在参数列表的后面,道理类似默认参数需后置
def say(name,*args):print(name,args)
say('嘉琪',170,100)   # 嘉琪 (170, 100)
# **kwargs 表示关键字参数,传输的数据格式:key=value
# 注意: **kwargs若和普通参数放在一起,必须将**kwargs放在参数列表的后面,否则会报错.
def say1(**kwargs):print(kwargs)
say1(name='张强',age = 22,height=175)  # {'name': '张强', 'age': 22, 'height': 175}def say2(name,**kwargs):print(name,kwargs)
say2('宏海',age = 24,weight = 140)  # 宏海 {'age': 24, 'weight': 140}
总结
  1. *args 和 **kwargs 都能表示不定长参数
  2. 在使用*args和**kwargs时,如果有普通参数,那普通参数必须放在前面,*args和 **kwargs放后面
  3. *args接收得到的是元组,**kwargs的到的是字典

3、匿名函数

特点

  1. lambda只是一个表达式,比普通函数简单
  2. lambda一般只会书写一行,包含了参数 函数体和返回值 先看普通函数
def fn(n):return n**2
res = fn(3)
print(res)  # 9
为了书写简单,引入了lambda表达式
使用匿名函数的方式实现上述的功能:
result = lambda n:n**2
print(result(3))  # 9
使用匿名函数计算两个数字的乘积:
fn = lambda n,m:n*m
print(fn2(12,4))  # 48
实现元组相乘
test = lambda *agr:agr*4
print(test(3,4))#(3, 4, 3, 4, 3, 4, 3, 4)
#这里函数是一个不定长的参数,的到的是一个元组
#实参传递3,4,的到的是元组(3,4)
#函数返回值是参数*4
#那的到的就是元组(3,4)*4 = (3, 4, 3, 4, 3, 4, 3, 4)

4、回调函数

概念: 若把函数名赋值给了一个新的变量,那这个变量就具备了和函数一样的功能.

下面我们直接通过代码来分析,代码也很简单,通过封装一个函数来实现加减乘除的操作

(1)先实现加、减、乘、除的函数

# 和
def add(a,b):print(a + b)
# 差
def cha(a,b):print(a - b)
# 乘积
def ji(a,b):print(a * b)
# 商
def shang(a,b):print(a / b)

(2)封装一个函数.实现加减乘除的操作

我们要的这个函数要求是传递,a,b两个要计算的实参以及计算方式(加、减、乘、除)的函数,然后的到结果

def common(a,b ,fn):fn(a,b)
# 加法
common(12,3,add)    # 15
# 减法
common(12,3,cha)    # 9
# 乘积
common(12,3,ji)     # 36
# 商
common(12,3,shang)  # 4.0

代码分析

  1. 我们定义一个common的函数,传递a,b以及计算方式(加、减、乘、除)的函数
  2. 在common函数中 fn是一个方法,当作一个参数传递进来
  3. 当执行 common(12,3,add) 时候,common函数里就执行add(12,3)从而达到根据传递不同的函数实现不同计算的功能

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Laravel序列化解码:深入Eloquent模型的序列化机制
  • 如何构建自己的交易机器人开发环境
  • 【机器学习】逻辑损失函数的基本概念和探索为什么平方误差损失函数不适用于逻辑回归以及探索逻辑损失函数
  • 基于supervisor制作基于环境变量配置的redis
  • MyBatis动态代理和映射器
  • 橙篇AI做产品经理,比Kimi爽多了
  • gpio的使用,---->使用sysfs 控制gpio(第二节)
  • RabbitMQ:MQ的可靠性
  • C#实现数据采集系统-系统优化服务封装
  • 捷行推出2024年8月专属福利活动
  • TDS传感器 - 从零开始认识各种传感器【二十五期】
  • websocket实现简易聊天室
  • Python连接数据库:JDBC不是唯一选择!
  • 什么是接口?
  • 【Pytorch实用教程】PyTorch中的Tensor拼接与组合以及其意义
  • hexo+github搭建个人博客
  • CSS相对定位
  • ES6--对象的扩展
  • express如何解决request entity too large问题
  • Java IO学习笔记一
  • Python进阶细节
  • QQ浏览器x5内核的兼容性问题
  • TCP拥塞控制
  • 微信小程序--------语音识别(前端自己也能玩)
  • 小而合理的前端理论:rscss和rsjs
  • 自定义函数
  • ​iOS实时查看App运行日志
  • ​批处理文件中的errorlevel用法
  • ## 1.3.Git命令
  • $LayoutParams cannot be cast to android.widget.RelativeLayout$LayoutParams
  • (java版)排序算法----【冒泡,选择,插入,希尔,快速排序,归并排序,基数排序】超详细~~
  • (pt可视化)利用torch的make_grid进行张量可视化
  • (理论篇)httpmoudle和httphandler一览
  • (七)c52学习之旅-中断
  • (三) diretfbrc详解
  • (四)Controller接口控制器详解(三)
  • (已解决)报错:Could not load the Qt platform plugin “xcb“
  • (转) ns2/nam与nam实现相关的文件
  • (转)Java socket中关闭IO流后,发生什么事?(以关闭输出流为例) .
  • (转)Linq学习笔记
  • ./configure、make、make install 命令
  • .NET 8.0 中有哪些新的变化?
  • .NET/C# 使用反射注册事件
  • .net6使用Sejil可视化日志
  • .NET使用HttpClient以multipart/form-data形式post上传文件及其相关参数
  • .NET学习教程二——.net基础定义+VS常用设置
  • .NET中GET与SET的用法
  • .vollhavhelp-V-XXXXXXXX勒索病毒的最新威胁:如何恢复您的数据?
  • ??eclipse的安装配置问题!??
  • @Autowired 和 @Resource 区别的补充说明与示例
  • @RequestBody与@ResponseBody的使用
  • @Transactional事务注解内含乾坤?
  • [30期] 我的学习方法
  • [7] CUDA之常量内存与纹理内存
  • [AIGC codze] Kafka 的 rebalance 机制