Python 的函式是怎麼傳遞引數的

2021-10-20 09:53:09 字數 1586 閱讀 2513

a = [1,2,3]

def foo(b):

foo(a)

print(a) # [1,2,3,4]

def bar(c):

c = [0,0,0]

bar(a)

print(a) # [1,2,3,4]

既然說道傳值還是傳引用,就要說到c++了(據我所知python中沒有這些概念)。假定題主和讀者們對c++有所了解。首先複習一下實參和形參的概念,看foo函式,假設這是個c++函式,那麼foo(a)呼叫過程中,a就是實參,b就是形參,如果對這個概念模糊,好好看下c++primer中的關於函式引數傳遞那一部分的內容,此處不再贅述。再來看看傳值和傳引用:

傳引用是使用形參給實參取乙個別名(alias),函式中對形參的操作實際上就是對實參的操作,來舉個c++中傳引用的例子:

//命名空間和標頭檔案此處省略了

void test(vector& vi);}

int main()

; test(v); // 因為是傳引用,執行結束後 v 變成了vector

return 0;

}

可以看到python也不是傳引用,把 bar 函式與此處的 test 函式作對比就知道了, 注意執行bar(a)以後,a不是[0,0,0], a沒有改變,所以有答案說對於可變物件是傳引用的說法我認為是不對的。

所以,既不是傳值也不是傳引用!要搞清楚python函式如何傳引數這個問題,本質上要搞清楚的是python中的"name binding",我盡量用自己的話解釋簡潔一點,更多細節參看最後的鏈結。我把a, b, foo, bar 這些東西叫做name,而不是叫變數,因為如果使用乙個未定義的東西xx,python會報 nameerror: name 'xx' is not defined。python中name是沒有型別的,而name所指向的物件是有型別的,比如name a 可以指向物件int數1,你也可以讓它指向乙個list物件。來看下面的**:

x = 1

y = x

print(y is x) #true 注意此處的is用來比較 y 與 x 所指向的物件是否為同乙個,也就是id(x)與id(y)是不是一樣的

# id方法返回的是某物件的id號(乙個int值),在其生命週期內保證唯一和不變, id(x)就是返回x所指向的物件的id

y = 2

print(y is x) # false

x += 1 # 此時x的值為2, x繫結到了物件 int2 上,同時id(x)也會發生改變

print(y is x) # true

x = 1表示的是給物件int 1繫結了(binging)乙個名字(name)叫做x,可以用名字 x來引用int 1 這個物件了。而 y=x 表示的是,現在y 也是物件int 1 的乙個名字了,也可以用名字 y來引用物件int 1 了。而y和x是同乙個物件的name,所以y is x返回true。現在 y=2, y is x 就是false了,因為name x 和y 指向了不同的物件。 x+=1, 此時注意 id(x)會發生改變, 返回的id是物件int 2的id了。那麼你再執行 y is x,就返回true, 因為它們都指向物件int 2。

python函式是值傳遞還是引用傳遞

在網上看python的基礎知識,看到函式這一章的時候,看到這麼一段話 所有引數 自變數 在python裡都是按引用傳遞。如果你在函式裡修改了引數,那麼在呼叫這個函式的函式裡,原始的引數也被改變了。def changeme mylist 修改傳入的列表 print 函式內取值 mylist retur...

js函式傳參是按值傳遞還是按引用傳遞?

基本型別 引用型別 閒扯完了,開始寫今天要總結的基礎知識。基本型別 undefined null boolean number string五種 簡單的資料段 引用型別 object 由多個值構成 兩種型別在使用上的區別 複製變數 這塊好理解,看乙個例子的對比就秒懂 基本型別 var num1 5 ...

python函式形參傳遞注意事項

說到這個問題,我們先來看一段 coding utf 8 author 15025 time 2021 3 12 10 19 software pycharm description def max if a b print a b a 5b 3max a b 此時有輸出結果,輸出為print函式中定...