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 的參數傳遞是引用傳遞