Python参数的传递机制,能传递爱吗?

Hello,小伙伴们,我是知道。

在工作中,很多人经常会遇到:代码写完一测试,发现结果和自己期望的不一样,于是开始一层层地 debug。花了很多时间,可到最后才发现,是传参过程中数据结构的改变,导致的程序问题。

比如,我将一个列表作为参数传入另一个函数,期望列表在函数运行结束后不变,但是往往事与愿违,由于某些操作,它的值改变了,那就很有可能带来后续程序一系列的错误。

因此,了解 Python 中参数的传递机制,这往往能让我们写代码时少犯错误,提高效率,是具有十分重要的意义。今天我们就一起来学习一下,Python 中参数是如何传递的。

1、什么是值传递和引用传递

有两种常见的参数传递:值传递和引用传递。

值传递,通常就是拷贝参数的值,然后传递给函数里的新变量。这样,原变量和新变量之间互相独立,互不影响。

引用传递,通常是指把参数的引用传给新的变量,这样,原变量和新变量就会指向同一块内存地址。如果改变了其中任何一个变量的值,那么另外一个变量也会相应地随之改变。

那么 Python 中,参数传递到底是如何进行的呢?它们到底属于值传递、引用传递,还是其他呢?

2、Python 变量及其赋值

先来看一段示例代码:

这里首先将 1 赋值于 a,即 a 指向了 1 这个对象,接着 b = a 则表示,让变量 b 也同时指向 1 这个对象。(注:Python 里的对象可以被多个变量所指向或引用)

最后执行 a = a + 1。需要注意的是,Python 的数据类型,例如整型(int)、字符串(string)等等,是不可变的。所以,a = a + 1,并不是让 a 的值增加 1,而是表示重新创建了一个新的值为 2 的对象,并让 a 指向它。但是 b 仍然不变,仍然指向 1 这个对象。因此,最后的结果是,a 的值变成了 2,而 b 的值不变仍然是 1。

通过这个例子你可以看到,这里的 a 和 b,开始只是两个指向同一个对象的变量而已,或者你也可以把它们想象成同一个对象的两个名字。简单的赋值 b = a,并不表示重新创建了新对象,只是让同一个对象被多个变量指向或引用。

同时,指向同一个对象,也并不意味着两个变量就被绑定到了一起。如果你给其中一个变量重新赋值,并不会影响其他变量的值。明白了这个基本的变量赋值例子,我们再来看一个列表的例子:

同样的,我们首先让列表 和同时指向了这个对象。

由于列表是可变的,所以 不会创建新的列表,只是在原列表的末尾插入了元素 4,变成。由于 和同时指向这个列表,所以列表的变化会同时反映在 和这两个变量上,那么, 和 的值就同时变为了。

另外,需要注意的是,Python 里的变量可以被删除,但是对象无法被删除。比如下面的代码:

删除了 这个变量,从此以后你无法访问 l,但是对象仍然存在。Python 程序运行时,其自带的垃圾回收系统会跟踪每个对象的引用。如果除了 外,还在其他地方被引用,那就不会被回收,反之则会被回收。

由此可见,在 Python 中:

变量的赋值,只是表示让变量指向了某个对象,并不表示拷贝对象给变量;而一个对象,可以被多个变量所指向。

可变对象(列表,字典,集合等等)的改变,会影响所有指向该对象的变量。

对于不可变对象(字符串、整型、元组等等),所有指向该对象的变量的值总是一样的,也不会改变。但是通过某些操作(+= 等等)更新不可变对象的值时,会返回一个新的对象。

变量可以被删除,但是对象无法被删除。

3、Python 函数的参数传递

Python 的参数传递是赋值传递 ,或者叫作对象的引用传递。Python 里所有的数据类型都是对象,所以参数传递时,只是让新变量与原变量指向相同的对象而已,并不存在值传递或是引用传递一说,代码示例:

这里的参数传递,使变量 x 和 y 同时指向了 1 这个对象。但当我们执行到 x = 2 时,系统会重新创建一个值为 2 的新对象,并让 x 指向它;而 y 仍然指向 1 这个对象。所以,y的值不变,仍然为 1。

那么对于上述例子的情况,是不是就没有办法改变 y 的值了呢?答案当然是否定的,我们只需稍作改变,让函数返回新变量,赋给 y。这样,y 就指向了一个新的值为 2 的对象,y的值也因此变为 2。

不过,当可变对象当作参数传入函数里的时候,改变可变对象的值,就会影响所有指向它的变量。比如下面的例子:

这里 x 和 y 先是同时指向值为的列表。不过,由于列表可变,执行 append() 函数,对其末尾加入新元素 4 时,变量 x 和 y 的值也都随之改变了。

但是,下面这个例子,看似都是给列表增加了一个新元素,却得到了明显不同的结果。

为什么y 仍然是,而不是呢?

要注意,这里,表示创建了一个“末尾加入元素 4“的新列表,并让 x 指向这个新的对象。这个过程与y 无关,因此y的值不变。当然,同样的,如果要改变 y 的值,我们就得让上述函数返回一个新列表,再赋予y 即可,这里你尤其要记住的是,改变变量和重新赋值的区别:

4、小结

今天,我们一起探讨了 Python 的变量及其赋值的基本原理,并且解释了 Python 中参数是如何传递的。和其他语言不同的是,Python 中参数的传递既不是值传递,也不是引用传递,而是赋值传递,或者是叫对象的引用传递。

需要注意的是,这里的赋值或对象的引用传递,不是指向一个具体的内存地址,而是指向一个具体的对象。

可变对象,当其改变时,所有指向这个对象的变量都会改变。

不可变对象,简单的赋值只能改变其中一个变量的值,其余变量则不受影响。

清楚了这一点,如果你想通过一个函数来改变某个变量的值,通常有两种方法。一种是直接将可变数据类型(比如列表,字典,集合)当作参数传入,直接在其上修改;第二种则是创建一个新变量,来保存修改后的值,然后将其返回给原变量。在实际工作中,我们更倾向于使用后者,因为其表达清晰明了,不易出错。

       

最新资讯

文档百科

周勃等大臣为何在刘邦死后15年,杀光他的嫡孙?

刘邦死后15年,周勃、灌婴等托孤大臣发动政变,杀光了他的嫡孙。因为周勃等人为的是大汉江山。刘邦立这个规矩,显然是为了保障刘氏的超然地位。也就是说,吕后大封诸吕,既得罪了刘氏子弟,又违背了刘邦的意愿,站到了大臣们的对立面。而刘邦的嫡孙,也在诛灭诸吕之后被杀。刘邦只有一个嫡子,就是刘盈,刘盈的儿子才是刘邦的嫡脉之孙。

李宁和中国李宁是一个品牌吗?

李宁近几年的一个发展可谓是不断的往上走,走出国门参加时装周,悟道系列现在很多的国外的人都开始穿了起来,其中不乏很多nba的明星,还有李宁韦德之道也是大热的系列之一。中国李宁和原来的李宁是同一个运动品牌,叫中国李宁品牌是为了更好的推向国际市场。

红钻石和红宝石的区别介绍

以上就是关于红钻石和红宝石区别的介绍,其实无论红钻石还是红宝石,都是大自然赠予我们的珍宝,它们不仅具有昂贵的金钱价值,并且有着非同寻常的文化内涵。

青鳉鱼和食蚊鱼有什么区别,可以混养吗

青鳉鱼和食蚊鱼在外观方面的相似程度还是比较高的,但它们也有一定的区别。首先是繁殖方面,青鳉鱼是一种卵生的鱼,会生出鱼卵。还有,青鳉鱼在光线照射下眼睛会反光,食蚊鱼则没有此特点。

鱼竿炮台什么牌子好?

炮台是钓鱼重要的辅助工具,别称竿架、支架、竿挂等,使用时插在岸边或安装在钓椅、钓箱上,作钓或可将鱼竿放在支架上解放双手,事实上竿架也是体现钓鱼属于休闲活动的基础工具,下面来看一看鱼竿炮台什么牌子好吧!

草鱼出血病发病原因及防治方法

草鱼是我国比较常见的淡水鱼类,现在养殖的农民朋友也越来越多,但是有些农民朋友疏于管理,导致草鱼引发各种疾病,造成大面积减产,所以要想提高草鱼养殖经济效益,就要做好鱼病的防治,接下来一起了解下草鱼出血病的发病原因及防治方法吧!

CopyRight © 2000~2023 一和一学习网 Inc.All Rights Reserved.
一和一学习网:让父母和孩子一起爱上学习