结论
传值或者传引用,是C/C++的函数参数的传递方式;
Python中没有所谓传值或者传引用,所以此问题没有意义,Python有着自己的一套独特的传参方式,是其动态语言的性质决定的;
细节
1. 传递的是不可变参数
在Python中,所有的不可变对象(mutable)是共享内存的,如int, float, bool, string, tuple。见下面的例子:
所以:
- 传递不可变对象时,如果只读该参数值,那么等同于传引用,因为实参形参都指向同一内存;Python为了提高效率,会使用公共的对象。
- 传递不可变对象时,如果“修改”该变量的话,那么其实是将该变量的“标签”贴到另一个对象上,即指向另一块内存地址,效果上类似于传值。
2. 传递的是可变参数
- 在Python中,不可变对象(mutable)不共享内存,如list, set, dict;
- 传递可变对象参数时,如果是只读或修改该参数,那么等同于传引用;
要注意的是,这里所说的“修改”,指的是:(1)类似于pop(), append(), insert()之类的操作;(2)基于下标的更改;(3)+=之类(在Python中通过调用__iadd__方法实现,而不是赋值操作符); - 传递可变对象参数时,如果直接对其进行了赋值操作(如第10行),那么不能算作修改,而是重新创建了一个对象,并指向开辟新的内存,此时等同于传值。
这里的赋值操作与C++有区别,具体细节可看:https://blog.csdn.net/weixin_37349233/article/details/116933463
补充
在很多博客上,都有这样一段话:
如果函数收到的是一个可变对象(比如字典 或者列表)的引用,就能修改对象的原始值——相当于通过“传引用”来传递对象。
如果函数收到的是一个不可变对象(比如数字、字符或者元组)的引用,就不能 直接修改原始对象——相当于通过“传值”来传递对象
这段话确实是正确的,但是要准确理解其中提到的“修改”二字的含义。
在Python中,赋值不能算做修改,因为会创建新内存。