先说结论:Python中统一都是引用传递。
理解变量和对象
-
我们都知道,Python中一切事物皆是对象,变量是对对象在内存中的存储的地址的抽象。所有的变量都可以理解是内存中一个对象的引用。
-
画图理解如下:
- 赋值语句“=”是将右侧对象中的内存地址赋给左侧的变量
a = "123"
-
执行上面这个赋值语句的时候,Python解释器首先在内存中创建一个字符串"123"对象。之后在内存中创建一个名为"a"的变量,将"a"指向"123"(将"123"的地址保存到“a”中)
接下来执行语句
b = a
- 因为a已经存在,所以不会创建a,会创建变量"b",并将"b"指向"a"指向的字符串"123"
再执行
a = "456"
-
a还是存在的,会创建字符串"456", 然后将"456"的地址赋给"a"
整个过程我们可以通过调用id()方法查看变量所指向对象在内存中的地址。
In [19]: a = "123"
In [20]: id(a)
Out[20]: 2168312990064
In [21]: b = a
In [22]: id(b)
Out[22]: 2168312990064 # 这里a, b的地址相同
In [23]: b
Out[23]: '123'
In [24]: a = "456"
In [25]: a
Out[25]: '456'
In [26]: b
Out[26]: '123'
In [27]: id(a)
Out[27]: 2168313026416 # 这里a的地址指向"456"
Python的引用传递
- 上面我们理解了变量和对象。Python对象可以分为可变对象(list, dic, set等)和不可变对象(tuple, string, number)两种。
- 当传递的参数是可变对象的引用时,由于可变对象的值可以修改,因此可以通过修改参数值而修改原对象,这类似于C语言中的引用传递;
- 当传递的参数是不可变对象的引用时,虽然传递的是引用,参数变量和原变量都指向同一内存地址,但是不可变对象无法修改,所以参数的重新赋值不会影响原对象,这类似于C语言中的值传递。
- 其他:具体深拷贝浅拷贝问题可看我之前的文章内容。
Python 浅拷贝、深拷贝详细图文解析
网友评论