python函式傳參是傳值還是傳引用?

2021-08-03 11:26:23 字數 2564 閱讀 4261

首先還是應該科普下函式引數傳遞機制,傳值和傳引用是什麼意思?

函式引數傳遞機制問題在本質上是呼叫函式(過程)和被呼叫函式(過程)在呼叫發生時進行通訊的方法問題。基本的引數傳遞機制有兩種:值傳遞和引用傳遞。

值傳遞(passl-by-value)過程中,被調函式的形式引數作為被調函式的區域性變數處理,即在堆疊中開闢了記憶體空間以存放由主調函式放進來的實參的值,從而成為了實參的乙個副本。值傳遞的特點是被調函式對形式引數的任何操作都是作為區域性變數進行,不會影響主調函式的實參變數的值。

引用傳遞(pass-by-reference)過程中,被調函式的形式引數雖然也作為區域性變數在堆疊中開闢了記憶體空間,但是這時存放的是由主調函式放進來的實參變數的位址。被調函式對形參的任何操作都被處理成間接定址,即通過堆疊中存放的位址訪問主調函式中的實參變數。正因為如此,被調函式對形參做的任何操作都影響了主調函式中的實參變數。

在python中實際又是怎麼樣的呢?
from ctypes import *

import os.path

import sys

deftest

(c):

print("test before")

print(id(c))

c+=2

print("test after")

print(id(c))

return c

if __name__ == '__main__':

a = 2

print("main before invoke test")

print(id(a))

n = test(a)

print("main after invoke test")

print(a)

print(id(a))

結果如下:

main before invoke test

1483651568

test before

1483651568

test after

1483651632

main after invoke test

21483651568

id函式可以獲得物件的記憶體位址.很明顯從上面例子可以看出,將a變數作為引數傳遞給了test函式,傳遞了a的乙個引用,把a的位址傳遞過去了,所以在函式內獲取的變數c的位址跟變數a的位址是一樣的,但是在函式內,對c進行賦值運算,c的值從2變成了4,實際上2和4所佔的記憶體空間都還是存在的,賦值運算後,c指向4所在的記憶體。而a仍然指向2所在的記憶體,所以後面列印a,其值還是2.

如果還不能理解,先看下面例子:

>>> a=1

>>> b=1

>>> id(a)

>>> id(b)

>>> a=2

>>> id(a)

那python函式傳參就是傳引用?然後傳參的值在被調函式內被修改也不影響主調函式的實參變數的值?再來看個例子。

def

test1

(list2):

print("test before")

print(id(list2))

list2[1] = 30

print("test after")

print(id(list2))

return list2

if __name__ == '__main__':

list1 = ["man",25,"woman"]

print("main before invoke test")

print(id(list1))

list3 =test1(list1)

print("main after invoke test")

print(list1)

print(id(list1))

結果如下:

main before invoke test

2093559227528

test before

2093559227528

test after

2093559227528

main after invoke test

['man', 30, 'woman']

2093559227528

發現一樣的傳值,而第二個變數居然變化,為啥呢?

>>> list1=[1,2]

>>> id(list1)

>>> list1[0]=[0]

>>> list1

[[0], 2]

>>> id(list1)

結論:python不允許程式設計師選擇採用傳值還是傳引用。python引數傳遞採用的肯定是「傳物件引用」的方式。這種方式相當於傳值和傳引用的一種綜合。如果函式收到的是乙個可變物件(比如字典或者列表)的引用,就能修改物件的原始值--相當於通過「傳引用」來傳遞物件。如果函式收到的是乙個不可變物件(比如數字、字元或者元組)的引用,就不能直接修改原始物件--相當於通過「傳值』來傳遞物件。

python函式傳參是傳值還是傳引用?

首先還是應該科普下函式引數傳遞機制 傳值和傳引用是什麼意思?函式引數傳遞機制問題在本質上是呼叫函式 過程 和被呼叫函式 過程 在呼叫發生時進行通訊的方法問題。基本的引數傳遞機制有兩種 值傳遞和引用傳遞。值傳遞 passl by value 過程中,被調函式的形式引數作為被調函式的區域性變數處理,即在...

python函式傳參是傳值還是傳引用?

首先還是應該科普下函式引數傳遞機制,傳值和傳引用是什麼意思?函式引數傳遞機制問題在本質上是呼叫函式 過程 和被呼叫函式 過程 在呼叫發生時進行通訊的方法問題。基本的引數傳遞機制有兩種 值傳遞和引用傳遞。值傳遞 passl by value 過程中,被調函式的形式引數作為被調函式的區域性變數處理,即在...

python函式傳參是傳值還是傳引用?

函式引數傳遞機制問題在本質上是呼叫函式 過程 和被呼叫函式 過程 在呼叫發生時進行通訊的方法問題。基本的引數傳遞機制有兩種 值傳遞和引用傳遞。值傳遞 passl by value 過程中,被調函式的形式引數作為被調函式的區域性變數處理,即在堆疊中開闢了記憶體空間以存放由主調函式放進來的實參的值,從而...