2017-03-15 56 views
2

我有,我想先出以下兩個最小的類來說明之前,我詳細講解了以下問題:傳遞名單方法類

class Example1: 

    def __init__(self): 
     pass 

    def function11(self,x): 
     x=2*x+1 
     return x 

    def function12(self,x): 
     y=0 
     z=x 
     while y<z: 
      x=self.function11(x) 
      y=y+1 
     return x 

class Example2:# the only difference to the previous class: it handles 
       #lists instead of numbers 

    def __init__(self): 
     pass 

    def function21(self,x): 
     x[0]=2*x[0]+1 
    return x 

    def function22(self,x): 
     y=0 
     z=x[0] 
     while y<z: 
      x=self.function21(x) 
      y=y+1 
     return x  



if __name__=="__main__": 
    A1=Example1() 
    x1=A1.function11(3) 
    y1=A1.function12(x1) 
    print'Result of Example1:' 
    print x1 
    print y1 
    print 

    A2=Example2() 
    x2=A2.function21([3]) 
    y2=A2.function22(x2) 
    print'Result of Example2:' 
    print x2 
    print y2 

這裏是輸出:

Result of Example1: 
7 
1023 

Result of Example2: 
[1023] 
[1023] 
>>> 

我在這裏不明白:爲什麼用y2的值覆蓋變量x2?這顯然取決於列表是Python中的可變對象,我是對的嗎?我在這方面的搜索使我得到了Effbot的一篇文章。不過,我並不十分了解這裏發生了什麼。

+0

因爲在'Example2.function21'中傳遞一個list對象,並通過它的索引(在'x [0] = 2 * x [0] + 1')中進行變異。在'Example1.function11'中,你並沒有改變原始變量(只需通過'x = 2 * x + 1'將名稱重新分配給不同的對象) – SuperSaiyan

+0

閱讀[這個答案](http://stackoverflow.com//23852480/assign-value-in-python-dict-copy-vs-reference)可能會有所幫助 – holdenweb

回答

0

Example1Example2之間的區別是,你在Example1返回一個值,但在Example2一個列表
Example2返回傳遞給它的相同列表,因此,當您撥打function22時,您是重複使用相同的列表,因此它的值會被覆蓋。

1

function12 and function12不會改變它們的輸入參數(順便說一下,對於不可變類型如int,這是不可能的)。他們只是根據參數計算結果,將名稱x重新命名爲該計算的值,然後返回該結果。

function21 and function22mutate他們的輸入參數,然後返回它。

這就是它的全部。這裏是有和無副作用對他們的輸入參數的函數較短的示範:

>>> def no_sideeffects(x): 
...  return x + [1] # build a new list and return the result, don't touch x 
... 
>>> x = [0] 
>>> no_sideeffects(x) 
[0, 1] 
>>> x 
[0] 
>>> 
>>> def sideeffects(x): 
...  x[0] = 23 # mutate x, i.e. change value at index 0 
...  return x # then return it 
... 
>>> x 
[0] 
>>> sideeffects(x) 
[23] 
>>> x 
[23]