2020年6月1日,天气,小雨,工位前java
小方啊,这 python 究竟是值传递仍是引用传递呢python
引用传递啊老板c++
那为何我看有人说什么不可变对象引用传递,可变对象值传递呢?你快给我好好讲讲web
好吧...数组
python 的参数传递是 「引用传递」编辑器
要研究这个问题,首先要明白 python 中关于「对象」的定义函数
python 中「万物皆可对象」url
以 java 为对照,咱们知道 java 中分为基本数据类型,好比整型 int,字节类型 char,布尔类型 boolean,它们在 java 中不可再分。而对象以基本数据类型和其余对象为基础,结合函数组装而成的,对象包含属性和方法。这就是 java 的数据类型spa
而在 python 中,不管是表示数字的 number,字符串 string,甚至是函数,它们都是做为对象的。python 中不分基本数据类型和对象,只有可变对象和不可变对象指针
什么是「不可变对象」呢?
首先咱们要明确「变量」的概念。变量是一个指向内存空间的引用,在 c++里咱们把它称为指针。
咱们在定义一个变量的时候经常会给它赋值a = 1
,其实是把一块存储数据为1
的内存空间和引用a
联系起来,变量a
指向内存空间。咱们说的不可变,就是指 这块内存空间存储的值不可变
不信咱们能够试一下:定义一个字符串s
,修改第一个字符的值
s = 'nihao'
s[0] = 'a'
print(s)
复制代码
咱们再来看一下对变量赋值的状况
咱们常常会重复修改一个变量的值
a = 10
···
a = 100
复制代码
借用一个id()
内置函数,该函数的做用是获取对象的内存地址,咱们用它分别打印变量a
每次赋值指向的内存地址
a = 10
print(id(a))
···
a = 100
print(id(100))
复制代码
能够看到,a
每次赋值指向的内存地址都不同。说明a
的第二次赋值并非把存储的10
改为100
,而是新建了一块数据为100
的内存空间,由a
指向新的内存空间。
因此,不可变对象的特色就是,内存空间的值没法被修改,每次赋值都是新建了一块新的内存空间
可变对象就很简单了,对变量的修改都直接做用在指向的内存空间上
在参数传递中,咱们的参数经常是以变量的形式出现的。参数传递的过程实际上是 函数外的变量经过「拷贝」传递给函数的参数
若是拷贝的是内存空间,就是「值传递」,拷贝的是引用,就是「引用传递」
咱们再用id()
函数看一下参数传递过程当中内存地址的变化
a = 10
def test(x):
print(id(x))
test(a)
print(id(a))
复制代码
能够看到,参数传递以前「实参指向的内存地址」和传递到函数内部「形参指向的内存地址」是同样的,证实python 的参数传递是引用传递