2011-11-18 80 views
6

看看下面的代碼我以爲Python通過引用傳遞了一切嗎?

#module functions.py 
def foo(input, new_val): 
    input = new_val 

#module main.py 
input = 5 
functions.foo(input, 10) 

print input 

我想輸入現在是10.這是爲什麼不是這樣?

+0

通過在函數foo的定義中調用局部變量「input」,您可能會迷惑自己。另外,斯文在答案中說。 – phkahler

+6

無論你在哪裏閱讀過,Python都會通過引用傳遞所有內容,它們是錯誤的。 –

回答

13

一切都按值傳遞,但該值是對原始對象的引用。如果修改對象,則更改對於調用者可見,但不能重新分配名稱。而且,許多對象是不可變的(整數,浮點數,字符串,元組)。

+8

「[習慣Python](http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html#other-languages-have-variables)」很好地說明了這種現象。 –

+1

Python不是按值或按引用調用,請參閱我的答案瞭解詳細信息。 –

+1

@skyhisi:除了使用非標準術語「按對象調用」之外,您的答案與我的答案基本相同,我故意避免使用非標準術語,因爲它沒有解釋任何事情。 –

8

在foo中,您將當地名稱input綁定到不同的對象(10)。在調用上下文中,名稱input仍指5對象。

5

Python中的賦值不會就地修改對象。它重新命名一個名稱,以便在input = new_val之後,本地變量input獲得新值。

如果要修改「外」 input,你必須把它包一個可變的對象內,如一個元素的列表:

def foo(input, new_val): 
    input[0] = new_val 

foo([input]) 

Python不通過就按引用就像C++引用傳遞的工作方式一樣。在這種情況下,至少,它更彷彿每個參數是在C/C++的指針:

// effectively a no-op! 
void foo(object *input, object *new_val) 
{ 
    input = new_val; 
} 
+0

感謝大家的回答......你提出的這個方法看起來幾乎就像一個黑客,這是標準程序嗎?有沒有其他方法可以修改更pythonic的不可變類型? (我想'修改不可變類型'回答我自己的問題,但我會問無論如何...) – Ferguzz

+0

@Ferguzz你不能通過定義修改不可變對象。但那真的是你要問的嗎?到目前爲止,甚至還沒有提到不可變對象。 「var = ...」不修改任何對象或任何其他變量的事實與不變性無關。你不能讓一個變量賦值改變另一個變量,就像你不能改變一個列表會影響另一個列表一樣。 – delnan

+0

我指的是這個答案中的一行'將它包裝在一個可變對象(如列表)中「。我試圖問,有沒有辦法像我原來的帖子那樣修改變量,而不這樣做? – Ferguzz

3

Python是既不呼叫按值,或呼叫按引用,它是Call By Object

「參數被調用的共享傳遞,類似到 呼叫按值,除了自變量的對象 ,如果他們是可變的,只能改變。」

+1

不錯的總結,但我仍然認爲逐個對象與按值調用沒有區別,所有「值」都是對象的句柄(〜=指針)。 – Kos

相關問題