python 函数参数传递机制_Python函数参数传递机制(超级详细)

Python中,函数参数由实参传递给形参的过程,是由参数传递机制来控制的。通过学习《Python函数值传递和引用传递》一节我们知道,根据实际参数的类型不同,函数参数的传递方式分为值传递和引用传递(又称为地址传递),本节将对这两种传递机制做深度剖析。

Python函数参数的值传递机制

所谓值传递,实际上就是将实际参数值的副本(复制品)传入函数,而参数本身不会受到任何影响。

值传递的方式,类似于《西游记》里的孙悟空,它复制一个假孙悟空,假孙悟空具有的能力和真孙悟空相同,可除妖或被砍头。但不管这个假孙悟空遇到什么事,真孙悟空都不会受到任何影响。与此类似,传入函数的是实际参数值的复制品,不管在函数中对这个复制品如何操作,实际参数值本身不会受到任何影响。

下面程序演示了函数参数进行值传递的效果:

def swap(a, b) :

# 下面代码实现a、b变量的值交换

a, b = b, a

print("swap函数里,a的值是", a, ";b的值是", b)

a = 6

b = 9

swap(a , b)

print("交换结束后,变量a的值是", a, "; 变量b的值是", b)

运行上面程序,将看到如下运行结果:

swap函数里,a的值是 9 ;b的值是 6

交换结束后,变量a的值是 6 ;变量b的值是 9

从上面的运行结果来看,在 swap() 函数里,a 和 b 的值分别是 9、6,交换结束后,变量 a 和 b 的值依然是 6、9。从这个运行结果可以看出,程序中实际定义的变量 a 和 b,并不是 swap() 函数里的 a 和 b 。

正如前面所讲的,swap() 函数里的 a 和 b 只是主程序中变量 a 和 b 的复制品。下面通过示意图来说明上面程序的执行过程。

上面程序开始定义了 a、b 两个局部变量,这两个变量在内存中的存储示意图如图 1 所示。

主栈区中 a、b 变量存储示意图

当程序执行 swap() 函数时,系统进入 swap() 函数,并将主程序中的 a、b 变量作为参数值传入 swap() 函数,但传入 swap() 函数的只是 a、b 的副本,而不是 a、b 本身。进入 swap() 函数后,系统中产生了 4 个变量,这 4 个变量在内存中的存储示意图如图 2 所示。

主栈区的变量作为参数值传入swap()函数后存储示意图

当在主程序中调用 swap() 函数时,系统分别为主程序和 swap() 函数分配两块栈区,用于保存它们的局部变量。将主程序中的 a、b 变量作为参数值传入 swap() 函数,实际上是在 swap() 函数栈区中重新产生了两个变量 a、b,并将主程序栈区中 a、b 变量的值分别赋值给 swap() 函数栈区中的 a、b 参数(就是对 swap() 函数的 a、b 两个变量进行初始化)。此时,系统存在两个 a 变量、两个 b 变量,只是存在于不同的栈区中而己。

程序在 swap() 函数中交换 a、b 两个变量的值,实际上是对图 2 中灰色区域的 a、b 变量进行交换。交换结束后,输出 swap() 函数中 a、b 变量的值,可以看到 a 的值为 9,b 的值为 6,此时在内存中的存储示意图如图 3 所示。

swap()函数中a、b 交换之后的存储示意图

对比图 3 与图 1,可以看到两个示意图中主程序栈区中 a、b 的值并未有任何改变,程序改变的只是 swap() 函数栈区中 a、b 的值。这就是值传递的实质:当系统开始执行函数时,系统对形参执行初始化,就是把实参变量的值赋给函数的形参变量,在函数中操作的并不是实际的实参变量。

Python函数参数的引用传递

如果实际参数的数据类型是可变对象(列表、字典),则函数参数的传递方式将采用引用传递方式。需要注意的是,引用传递方式的底层实现,采用的依然还是值传递的方式。

下面程序示范了引用传递参数的效果:

def swap(dw):

# 下面代码实现dw的a、b两个元素的值交换

dw['a'], dw['b'] = dw['b'], dw['a']

print("swap函数里,a元素的值是",\

dw['a'], ";b元素的值是", dw['b'])

dw = {'a': 6, 'b': 9}

swap(dw)

print("交换结束后,a元素的值是",\

dw['a'], ";b元素的值是", dw['b'])

运行上面程序,将看到如下运行结果:

swap函数里,a元素的值是 9 ;b元素的值是 6

交换结束后,a元素的值是 9 ;b元素的值是 6

从上面的运行结果来看,在 swap() 函数里,dw 字典的 a、b 两个元素的值被交换成功。不仅如此,当 swap() 函数执行结束后,主程序中 dw 字典的 a、b 两个元素的值也被交换了。这很容易造成一种错觉,即在调用 swap() 函数时,传入 swap() 函数的就是 dw 字典本身,而不是它的复制品。但这只是一种错觉,下面还是结合示意图来说明程序的执行过程。

程序开始创建了一个字典对象,并定义了一个 dw 引用变量(其实就是一个指针)指向字典对象,这意味着此时内存中有两个东西:对象本身和指向该对象的引用变量。此时在系统内存中的存储示意图如图 4 所示:

主程序创建了字典对象后存储示意图

接下来主程序开始调用 swap() 函数,在调用 swap() 函数时,dw 变量作为参数传入 swap() 函数,这里依然采用值传递方式:把主程序中 dw 变量的值赋给 swap() 函数的 dw 形参,从而完成 swap() 函数的 dw 参数的初始化。值得指出的是,主程序中的 dw 是一个引用变量(也就是一个指针),它保存了字典对象的地址值,当把 dw 的值赋给 swap() 函数的 dw 参数后,就是让 swap() 函数的 dw 参数也保存这个地址值,即也会引用到同一个字典对象。图 5 显示了 dw 字典传入 swap() 函数后的存储示意图。

dw字典传入swap()函数后存储示意图

从图 5 来看,这种参数传递方式是不折不扣的值传递方式,系统一样复制了dw 的副本传入 swap() 函数。但由于 dw 只是一个引用变量,因此系统复制的是 dw 变量,并未复制字典本身。

当程序在 swap() 函数中操作 dw 参数时,由于 dw 只是一个引用变量,故实际操作的还是字典对象。此时,不管是操作主程序中的 dw 变量,还是操作 swap() 函数里的 dw 参数,其实操作的都是它们共同引用的字典对象,它们引用的是同一个字典对象。因此,当在 swap() 函数中交换 dw 参数所引用字典对象的 a、b 两个元素的值后,可以看到在主程序中 dw 变量所引用字典对象的 a、b 两个元素的值也被交换了。

为了更好地证明主程序中的 dw 和 swap() 函数中的 dw 是两个变量,在 swap() 函数的最后一行增加如下代码:

把dw 直接赋值为None,让它不再指向任何对象

dw = None

运行上面代码,结果是 swap() 函数中的 dw 变量不再指向任何对象,程序其他地方没有任何改变。主程序调用 swap() 函数后,再次访问 dw 变量的 a、b 两个元素,依然可以输出 9、6。可见,主程序中的 dw 变量没有受到任何影响。实际上,当在 swap() 函数中增加“dw =None”代码后,在内存中的存储示意图如图 6 所示。

将swap()函数中的dw赋值为None 后存储示意图

从图 6 来看,把 swap() 函数中的 dw 赋值为 None 后,在 swap() 函数中失去了对字典对象的引用,不可再访问该字典对象。但主程序中的 dw 变量不受任何影响,依然可以引用该字典对象,所以依然可以输出字典对象的 a、b 元素的值。

通过上面介绍可以得出如下两个结论:

不管什么类型的参数,在 Python 函数中对参数直接使用“=”符号赋值是没用的,直接使用“=”符号赋值并不能改变参数。

如果需要让函数修改某些数据,则可以通过把这些数据包装成列表、字典等可变对象,然后把列表、字典等可变对象作为参数传入函数,在函数中通过列表、字典的方法修改它们,这样才能改变这些数据。

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

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

相关文章

职称计算机 高级,职称全国计算机考试已通过三个模块,如何取得职称高级计算机...

类似问题答案2021年广西科技大学3月全国计算机等级全国计算机等级考试在哪里网上报名?2.全国计算机等级考试在哪里网上报名? 答:考生可登录广西科技大学继续教育学院网站(广西科技大学网站首页点击——继续教育——考试报名(2021年3月全国计算…

centos7已有数据硬盘挂载_干货!如何给虚拟机增加虚拟硬盘,Linux再分区挂载

很多朋友一开始给虚拟机的硬盘都很小,用着用着虚拟硬盘就不够了,今天小编就给大伙说说如何给虚拟机添加虚拟硬盘在到Linux系统下分区格式化再到挂载。点击创建新的虚拟盘我分配一个8g的硬盘吧!现在启动centos 7查看一下你刚刚添加的8G的硬盘&…

cad计算机绘注意事项,CAD制图的注意事项

CAD制图的注意事项CAD是应用比较广泛的软件,所以没有对某一行业的应用做优化,所以用起来可能不如一些专业的软件(如CAXA电子图版)那么方便,但正是因为它的这种广泛性,在很多工厂、单位、外企都使用这个软件作为正式绘图软件&#…

diy机器人图片 手绘纸箱_废物利用,她用几个纸箱让家里变成动物园,孩子回家乐坏了!收藏...

纸箱是我们日常生活中最常见的一种废品,现在随着网购的崛起,家里的纸箱越来越多,这时候你是直接丢弃,还是会想想是否可以再利用的价值?这些看似没用的纸箱,在创意妈的眼中可是个宝贝呢~它可以变废为宝成为孩…

计算机研究生考426分单科多少,考研初试426分,依然没被录取,他犯的错误,值得大家参考!...

原标题:考研初试426分,依然没被录取,他犯的错误,值得大家参考!最近几天,考研初试成绩陆续发布。考试分数比较高的考生,有机会参加复试,就要尽早准备复试复习了。复试成绩也很重要&am…

uniapp 表单页面_uniapp自定义表单模板经验分享

极简属性:data(仅提供方法和极简示例,实践党可自行扩展,伸手党请绕行)表单组件通用注:此data是组件的一个隐藏属性示例:template:{{sexs[grouplist.sexIndex].name}}data:sexs: [{name: "男…

毕业就业推荐表计算机,毕业生就业推荐表

一份好的就业推荐表自我鉴定,能让你在求职过程中加分不少,所以同学们要重视起就业推荐表自我鉴定的作用。下面是由出国留学网小编为大家整理的“2020高校毕业生就业推荐表自我鉴定”,仅供参考,欢迎大家阅读。2020高校毕业生就业推…

etal斜体吗 参考文献_参考文献的标准格式

2.文后参考文献编排格式(1)专著、论文集、学位论文、报告[序号]作者.文献题名[文献类型标识].出版地:出版者.出版年,起止页码(任选).范例:[1]杨浩滨.食品微生物学[M].北京:北京农业大学出版社,1…

70进货卖100利润是多少_一只周黑鸭随便就卖100多,那成本有多少?说出来你可能不信...

一只周黑鸭动不动就卖100多,那成本有多少?说出来你可能不信。如果你吃过周黑鸭,不知道每次想起的时候,尤其是午夜时分会不会有流口水的感觉,那种麻辣的口感,再搭配上冰凉爽口的啤酒,发自心底的那…

计算机网络实验报告访问控制列表,电子政务《计算机网络实验》期末报告 07-访问控制列表实验报告.doc...

文档介绍:计算机网络实验报告 1. 实验报告如有雷同,雷同各方当次实验成绩均以 0 分计。 2. 当次小组成员成绩只计学号、姓名登录在下表中的。 3. 在规定时间内未上交实验报告的, 不得以其他方式补交, 当次成绩按 0 分计。 4. 实验报告文件以 PDF 格式提交。【实验题…

powerquery加载pdf_pdf转换为excel,你不会,同事点点鼠标2分钟就搞定了

Hello.大家好,最近office365进行了一次小的更新,这次更新在excel中添加了获取pdf文件中的表格的功能,操作起来十分的简单,下面就跟大家分享下它是如何操作的首先我们新建一个excel文件,然后点击数据功能组,…

防火墙设置导致服务器站点打开,服务器、网站、环境配置全正常网站打不开原来是系统防火墙造成的...

大家都知道网站是架在服务器上的,通过域名解析指向网站并在服务器上绑定域名,上传网站程序到指定的目录,并只要有适合网站运行的环境,网站目录权限正常网站就肯定可以正常运行了,但今天我们技术遇到了一个问题以上所说…

web前端开发技术期末考试_智慧树来我校开展WEB前端开发微专业导学

11月17日,在6号教学楼6102阶梯教室,智慧树工作人员带来了WEB前端开发微专业导学。根据前期长青联盟微专业的报名情况及学生学习情况,为进一步提高学生学习微专业的质量,学院联系了微专业教学平台的专家对教学平台的使用进行技术指…

计算机辅助设计还需要手绘吗,西安电脑如此发达为什么还要学习手绘

在处理器以八核成为主流、硬盘以T而论的今天,计算机辅助设计软件是设计师的得力工具。用铅笔、尺子要时间才能画好的一个室内空间平面布置图,如果用CAD可能一个小时都不用就完成了,而且很方便修改,可见在效率方面,电脑…

一键生成通讯录的软件_橙瓜码字自动写作软件,外貌描写对话描写一键生成

很多写手对于以古代为背景的小说,偶尔都会对某些地方感到棘手,有时候是历史的背景,有时候是当时的官制、称呼,或是一些特有的服饰,外貌的描写,而面对难题,很多时候我们也是选择上网查询&#xf…

gin 静态文件服务器拒绝,nginx实现简单的图片服务器(windows)+静态文件服务器-Go语言中文社区...

需求:能够使用 http://localhost/目录/图片名 访问本地(服务器)已经存在的图片首先需要在本地将nginx跑起来,这里使用默认端口80;在浏览器使用http://localhost看到下面的界面证明nginx启动正常。下面需要修改nginx.conf来实现直接使用http:/…

wegame每次登陆都要滑动验证_Vue项目中实现用户登录及token验证

在前后端完全分离的情况下,Vue项目中实现token验证大致思路如下:1、第一次登录的时候,前端调后端的登陆接口,发送用户名和密码2、后端收到请求,验证用户名和密码,验证成功,就给前端返回一个toke…

云服务器 性能监控软件,云监控 - 云应用监控 - ManageEngine Applications Manager

云监控什么是云监控?尽管许多组织仍然依赖于在自托管的数据中心中存储数据的本地方法,但在业务组织中采用云服务的情况已经逐渐增多。自然,这导致了一些云监控工具的出现。无论您使用的是公共、私有还是混合环境,对应用程序性能具有端到端可…

mysql导入dat文件_MySql导入和抽取大数量级文件数据

一、情况介绍需要处理的文件是一个3.41G的csv格式文件,现在需要把它导入数据库,进行后续处理和分析。二、导入数据该文件数据量庞大,无法用excel或者editplus之类普通软件打开,于是借用了pandas的方法查看了表的结构:方…

服务器操作系统与安装步骤,服务器操作系统与安装步骤

服务器操作系统与安装步骤 内容精选换一换如果在创建弹性云服务器时未设置密码,或密码丢失、过期,可以参见本节操作重置密码。密码丢失或过期前,已安装密码重置插件。公共镜像创建的弹性云服务器默认已安装一键重置密码插件。私有镜像创建的云…