2016-07-22 44 views
2

從Python的官方教程Chapter "Classes"調用者如何看到對象中的更改?

[...]如果函數修改作爲參數傳遞的對象,調用者可以看到的變化 - 這消除了兩個不同的參數傳遞機制的需要在帕斯卡。

什麼是調用者如何看到改變的例子?或者它怎麼會是這樣(不是在Python中,而是在一般情況下),調用者看不到變化?

回答

3

什麼是調用者如何看到改變的例子?

>>> def modify(x): 
...  x.append(1) 
... 
>>> seq = [] 
>>> print(seq) 
[] 
>>> modify(seq) 
>>> print(seq) 
[1] 

或者怎麼會是(不是在Python但一般)的調用者沒有看到改變?

可以想像,語言可能存在創建其中seq深拷貝並分配給x,並x所做的任何變化對seq沒有影響,在這種情況下print(seq)將顯示[]兩次。但這不是Python中發生的事情。


編輯:請注意,將新值分配給舊變量名稱通常不會算作「修改」。

>>> def f(x): 
...  x = x + 1 
... 
>>> y = 23 
>>> f(y) 
>>> print(y) 
23 
+0

在你的編輯:是不是因爲'int'是不可變的? – Leo

+0

即使分配給當前包含可變對象的標識符,本地分配在其當前範圍外也不可見。假設函數做了'x = x + [1]'。然後'z = []; F(z)的; print(z)'會打印'[]',即使列表是可變的。 – Kevin

3

它基本上意味着如果一個可變對象發生了變化,它會隨處變化。

爲了通過參考一個傳遞的示例(其是Python做什麼):

x = [] 
def foo_adder(y): 
    y.append('foo') 
foo_addr(x) 
print(x) # ['foo'] 

VS類似帕斯卡,在這裏可以傳遞一個對象的副本作爲參數,而不是對象本身:

# Pretend this is Pascal code. 
x = [] 
def foo_adder(y): 
    y.append('foo') 
foo_adder(x) 
print(x) # [] 

如果您傳遞對象的副本,則可以在Python中獲得第二個示例的行爲。對於列表,您使用[:]

# Pretend this is Pascal code. 
x = [] 
def foo_adder(y): 
    y.append('foo') 
foo_adder(x[:]) 
print(x) # [] 

你對如何調用者可能沒有看到改變,讓我們採取同樣的foo_adder功能和小改,這樣它不會修改對象,第二個問題,而是將其替換。

x = [] 
def foo_adder(y): 
    y = y + ['foo'] 
foo_adder(x) 
print(x) # [] 
+0

你錯過了在這兩個片段中實際調用'foo_adder'的步驟...... –

+0

@DanielRoseman我不知道你在說什麼。 ;) (感謝您指出了這一點)。 –

相關問題