【老板叫我了】python的参数传递是「值传递」仍是「引用传递」?

前言

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 的参数传递是引用传递

相关文章
相关标签/搜索