【老闆叫我了】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 的參數傳遞是引用傳遞

相關文章
相關標籤/搜索