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

pyhton基础【16】函数进阶二

目录

四.星号拆包

普通方式拆包

使用*拆包

使用**拆包

难点

五.变量引用

引用概念

赋值运算符

引用当做实参

六.函数引用


四.星号拆包
普通方式拆包

假如有以下函数:

def test(a, b, c):print(a + b + c)

现在自己拥有的数据:

nums = [11, 22, 33]

怎样才能在调用test函数的时候,将nums给传递过去呢?

def test(a, b, c):print(a + b + c)nums = [11, 22, 33]
test(nums[0], nums[1], nums[2])

上述代码用的方式虽然能行,但不是很简洁

为了能够用更加简洁的方式实现上述场景需求,Python可以通过*、**将数据拆包后传递

使用*拆包

有时在调用函数时,这个函数需要的是多个参数,而自己拥有的是一个列表或者集合这样的数据,此时就用可以用*拆包

使用方式:

*列表
*元组
*集合

用*拆包的方式实现上述功能:

def test(a, b, c):print(a + b + c)nums = [11, 22, 33]
test(*nums)  # 此时的*的作用就是拆包,此时*nums相当于11, 22, 33 即test(11, 22, 33)

如果为数据元组时使用方式与上述代码一致:

def test(a, b, c):print(a + b + c)nums = (11, 22, 33)
test(*nums)

集合类型同上:

def test(a, b, c):print(a + b + c)nums = {11, 22, 33}
test(*nums)

注意:*对列表、元组、集合可以拆包,但一般都是在调用函数时使用

使用**拆包

使用**可以对字典进行拆包,拆包的结果是命名参数

示例:

def test(name, age, address):print(name)print(age)print(address)info = {"name": "小明","age": 18,"address": "兰州"
}test(**info)'''
当前**info相当于以下代码:name='小明'age=18address='兰州'** 主要对字典进行拆包
'''
难点

学习不定长参数时,掌握了*args、**kwargs

现在学习拆包时,也用到了*、**

那它们之间有什么关系呢?

答:没有任何关系,只是长得像罢了

示例一:

def test1(*args, **kwargs):print("----在test1函数中----")print("args:", args)print("kwargs", kwargs)def test2(*args, **kwargs):print("----在test2函数中----")print("args:", args)print("kwargs", kwargs)test1(args, kwargs)  # 在函数test1传递参数时没有进行拆包test2(11, 22, 33, name="小明", age=18)运行结果:----在test2函数中----
args: (11, 22, 33)
kwargs {'name': '小明', 'age': 18}
----在test1函数中----
args: ((11, 22, 33), {'name': '小明', 'age': 18})
kwargs {}

示例二:

def test1(*args, **kwargs):print("----在test1函数中----")print("args:", args)print("kwargs", kwargs)def test2(*args, **kwargs):print("----在test2函数中----")print("args:", args)print("kwargs", kwargs)test1(*args, **kwargs)  # 对参数进行了拆包test2(11, 22, 33, name="小明", age=18)运行结果:
----在test2函数中----
args: (11, 22, 33)
kwargs {'name': '小明', 'age': 18}
----在test1函数中----
args: (11, 22, 33)
kwargs {'name': '小明', 'age': 18}
五.变量引用

引入

如下代码中,最后b的值为多少?

>>> a = 1
>>> b = a
>>> b
1
>>> a = 2
>>> a
2
>>> b
1

如下代码中,最后b的值为多少?

>>> a = [1, 2]
>>> b = a
>>> b
[1, 2]
>>> a.append(3)
>>> b
[1, 2, 3]
引用概念

引用:就是内存地址

那地址是什么呢?可以理解为存放数据的空间在内存中的编号

例如:

a = 100怎样知道它的地址呢?id(a)可以直接将上述的结果打印:print(id(a))运行结果(在不同机器上输出的地址可能不相同):4347271232

当我们知道了原来引用就是地址之后,再来看如下代码:

a = [1, 2]我们可以用id(a)取它的地址:print(id(a))  # 获取变量存储的引用(地址)是多少接下来定义变量b并且赋值:b = a此时输出变量b的引用:print(id(b))运行结果(不同机器上的内存地址可能不相同):4558971360
4558971360

这说明,此时变量a、b存储的引用都是相同的

由此我们可以得出一个结论:Python中的变量并不是真正存储数据,而是存储的数据所在内存中的地址,我们一般称之为引用

既然变量a、b都指向同一个列表,那么接下来:

a.append(3)

此时变量a、b指向的同一个列表中多了一个数据,即此时列表为[1, 2, 3]

所以a、b此时用print输出相同的结果。

补充内容:

大家自己试试看a=257, b=257时它们的id还是否会相等。事实上Python为了优化速度,使用了小整数对象池,避免为整数频繁申请和销毁内存空间。而Python对小整数的定义是[-5, 257),只有数字在-5到256之间它们的id才会相等,超过了这个范围就不行了,同样的道理,字符串对象也有一个类似的缓冲池,超过区间范围内自然不会相等了。 

赋值运算符

赋值运算符=,之前为了更好的理解变量,把a=100理解为变量a中存放了100,事实上变量a存储是100的引用

也就是说:在Python中只要用=那么就表示=左边的变量存储了一个新的引用

大白话讲:就是=左边的变量指向了右边的数据。

想想下面的代码运行的结果是什么?

a = [1, 2]
b = a
b.append(3)
b = [100, 200, 300]print(b)运行结果:
[100, 200, 300]而不是:
[1, 2, 3]
引用当做实参

Python中调用函数时,传递实参实际上都是是引用,即传递的都是地址

只要是传递的引用,那么也就是说在函数中是可以直接对指向的数据进行修改

def test(p):# 此时变量p也指向nums指向的列表p.append(44)print("在函数test中,p=", p)nums = [11, 22, 33]
print("调用test函数之前,nums=", nums)
test(nums)  # 此时将列表的引用当做了实参进行传递
print("调用test函数之后,nums=", nums)运行结果:
调用test函数之前,nums = [11, 22, 33]
在函数test中,p = [11, 22, 33, 44]
调用test函数之后,nums = [11, 22, 33, 44]
六.函数引用

阅读如下代码,思考会输出什么结果

def test1():print("我是test1函数...")def test2():print("我是test2函数...")test1()test1 = test2
test1()运行结果如下:
我是test1函数...
我是test2函数...

你可能会惊讶,为什么第九行调用test1函数输出的是我是test1函数...,反而到了第十二行再次调用test1函数时变成了我是test2函数...

上述问题的原因核心点是:在Python中即使是函数名也是一个变量名,只不过这个变量没有指向普通的数据,而是指向了一段代码;也就是说如果定义了一个函数名字叫做test1就好比是一个变量名test1指向了那个代码块而已,所以当上述代码第十一行test1 = test2时,就相当于让test1变量不在指向原本的代码块,而是指向新的代码块即test2指向的代码块,所以当第十二行执行test1函数时,会输出我是test2函数...

引用的作用

看完上述的引入知识后,相信你会对什么是函数的引入有一个大体的认知了

在此简单总结:所谓函数名当做引用,其实是指在Python中所有的函数名实际上是一个变量名,只不过这个变量名指向的不是常见的数据,而是一段代码,当我们用函数名()是实际上就是让指向的这块代码开始执行,当我们只用函数名时其实就是这个函数的引用

记住:既然函数名也是变量名,那么就可以给它赋值获取它的引用给别的变量

总结:

1. 使用def定义的函数名,实际就是个变量名它存储了函数的引用

2. 如果将另外一个变量,例如b保存了函数的引用,即也指向了同一个函数,那么b()就是调用函数

http://www.lqws.cn/news/519409.html

相关文章:

  • 仿Apple官网设计风格
  • HCIA-IP路由基础
  • 鸿蒙OH南向开发 轻量系统内核(LiteOS-M)【Shell】
  • 实测对比:用 Lynx 做网页,效率比传统工具提升 270% 的底层逻辑
  • 【Oracle学习笔记】4.索引(Index)
  • 【大厂机试题解法笔记】可以组成网络的服务器
  • FPGA基础 -- Verilog 格雷码(Gray Code)计数器设计与原理解析
  • 开疆智能CCLinkIE转ModbusTCP网关连接脉冲计数器配置案例
  • MySQL之存储过程详解
  • 自动化测试--Appium和ADB及常用指令
  • 分布式环境下 Spring Boot 项目基于雪花算法的唯一 ID 生成方案
  • php后台增加权限控制
  • LangGraph开篇-LangGraph 核心元素简介(官网文档解读)
  • Spring Web MVC ①
  • 用 Boost 库解析 .ini 和 .json 文件时的“坑”:注释导致的解析错误与解决方案
  • 湖北理元理律师事务所:债务规划中的法律与心理双轨模型
  • 如何在 Manjaro Linux 上安装 Docker 容器
  • OpenCV——cv::floodFill
  • 卷积神经网络(Convolutional Neural Network, CNN)
  • 使用pyflink编写demo并将任务提交到yarn集群
  • 大塘至浦北高速:解锁分布式光伏“交能融合”密码,引领绿色交通革命
  • Redis HyperLogLog误差率0.81%的由来:从算法原理到Redis实现
  • UNIAPP入门基础
  • 如何快速将iPhone中的文本保存到电脑上
  • [架构之美]在Linux上通过源码编译安装Nginx(十四)
  • golang实现一个mysql中随机获取cookies的API
  • 数字隔离器,如何扛起现代智能家电的电气安全“大旗”
  • [Java实战]Windows系统JDK21安装与JDK8切换指南(三十九)
  • 利用亮数据实现海外网站数据自动抓取
  • 回归预测 | Matlab实现KAN神经网络多输入单输出回归预测模型