1. 程式人生 > 程式設計 >Python引數傳遞實現過程及原理詳解

Python引數傳遞實現過程及原理詳解

在分析python的引數傳遞是如何進行的之前,我們需要先來了解一下,python變數和賦值的基本原理,這樣有助於我們更好的理解引數傳遞。

python變數以及賦值

數值

從幾行程式碼開始

In [1]: a = 1
In [2]: b = a
In [3]: a = a + 1

我們先將1賦值給a,也就是a指向了1這個物件,在python中一切皆物件。接著b=a,則表示讓b也指向了1這個物件,python中一個物件是可以被多個引用所指向。最後執行的a=a+1,這裡需要注意一點,python的資料型別中如int、str等不可變型別,執a=a+1這種操作,並不是把a指向的物件的值增加1,而是生成一個新的物件2,並讓a指向2這個物件,原來的物件還存在於記憶體中。那這裡的話還是會被指向,我們來分別看一下a和b的值:

In [4]: a
Out[4]: 2

In [5]: b
Out[5]: 1

通過這個例子你可以看到,這裡的 a 和 b,開始只是兩個指向同一個物件的變數而已,或者你也可以把它們想象成同一個物件的兩個名字。簡單的賦值 b = a,並不表示重新建立了新物件,只是讓同一個物件被多個變數指向或引用。同時,指向同一個物件,也並不意味著兩個變數就被繫結到了一起。如果你給其中一個變數重新賦值,並不會影響其他變數的值。

列表

還有一個列表的例子,再來瞅瞅:

In [6]: l1 = [3,4,5,6]
In [7]: l2 = l1
In [10]: l1.append(7)
In [11]: l1
Out[11]: [3,6,7]
In [12]: l2
Out[12]: [3,7]

程式碼中,我們讓l1和l2這兩個變數都指向了[3,6]這個物件,我們知道列表是一種可變的資料結構,所以append操作並不會產生新的物件,只是在末尾添加了一個元素,變成了[3,7],由於 l1 和 l2 同時指向這個列表,所以列表的變化會同時反映在 l1 和 l2 這兩個變數上,那麼,l1 和 l2 的值就同時變為了[3,7]。

物件刪除

python中變數是可以刪除的,但是物件是沒辦法刪除的

In [22]: a = [1,5]

In [23]: del a

del語句刪除a這個變數,就無法通過a訪問[1,5],但是這個物件在存在中還是存在的,python的垃圾回收機制發現引用為0的時候就會把它回收掉。

總結

  • 變數的賦值,只是表示讓變數指向了某個物件,並不表示拷貝物件給變數;而一個物件,可以被多個變數所指向
  • 可變物件(列表,字典,集合等等)的改變,會影響所有指向該物件的變數
  • 對於不可變物件(字串、整型、元組等等),所有指向該物件的變數的值總是一樣的,也不會改變。但是通過某些操作(+= 等等)更新不可變物件的值時,會返回一個新的物件
  • 變數可以被刪除,但是物件無法被刪除

python函式是如何進行引數傳遞的

python的引數傳遞是賦值傳遞或者說是引用傳遞,python裡一切皆物件,所以引數傳遞時,只是讓新變數與原變數指向了同一個物件,下面我們來看個例子:

In [28]: def func(b):
  ...:   b = 2

In [29]: a = 1

In [30]: func(a)

In [31]: a
Out[31]: 1

這裡的引數傳遞,使變數 a 和 b 同時指向了 1 這個物件。但當我們執行到 b = 2 時,系統會重新建立一個值為 2 的新物件,並讓 b 指向它;而 a 仍然指向 1 這個物件。所以,a 的值不變,仍然為 1。

如何改變a的值呢?

我們可以在函式中將b返回

def func(b):
  b = 2
  return b
a = 1
a = func(a)
a
2

上面的例子我們的是int型別的,下面我們看一下列表的例子:

def func(l2):
  l2.append(77)

l1 = [12,3,6]
func(l1)
l1
[12,77]

這裡 l1 和 l2 先是同時指向值為[1,2,3]的列表。不過,由於列表可變,執行 append() 函式,對其末尾加入新元素 4 時,變數 l1 和 l2 的值也都隨之改變了.

那大家看一下面的例子,結果是什麼呢?

def func(l2):
  l2 = l2 + [4]

l1 = [12,6]

可以看到,l1沒有發生變化,原因是l2 + [4]這個操作表示建立了一個末尾加入元素 4的新列表,並讓 l2 指向這個新的物件,l1還是指向原有的物件。

總結

今天,我們討論了 Python 的變數及其賦值的基本原理,並且解釋了 Python 中引數是如何傳遞的。和其他語言不同的是,Python 中引數的傳遞既不是值傳遞,也不是引用傳遞,而是賦值傳遞,或者是叫物件的引用傳遞。需要注意的是,這裡的賦值或物件的引用傳遞,不是指向一個具體的記憶體地址,而是指向一個具體的物件。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。