2013-09-05 60 views
6

我有一個小問題,我不明白。Python - 爲什麼它不創建對象的新實例?

我有一個方法:

def appendMethod(self, newInstance = someObject()): 
    self.someList.append(newInstace) 

我把這種方法不帶屬性:

object.appendMethod() 

而實際上我追加列表與someObject的同一個實例。

但是,如果我將其更改爲:

def appendMethod(self): 
    newInstace = someObject() 
    self.someList.append(newInstance) 

我每次都獲得該對象的新實例,有什麼區別?

下面是一個例子:

class someClass(): 
    myVal = 0 

class otherClass1(): 

    someList = [] 

    def appendList(self): 
     new = someClass() 
     self.someList.append(new) 

class otherClass2(): 

    someList = [] 

    def appendList(self, new = someClass()): 
     self.someList.append(new) 

newObject = otherClass1() 
newObject.appendList() 
newObject.appendList() 
print newObject.someList[0] is newObject.someList[1] 
>>>False 

anotherObject = otherClass2() 
anotherObject.appendList() 
anotherObject.appendList() 
print anotherObject.someList[0] is anotherObject.someList[1] 
>>>True 
+0

這個問題是不是* *嚴格相關的可變默認值,但大約是*創建*默認值時。 @tomek記住,每個函數都在'__defaults__'屬性中保存了默認值的一個**元組**。但是,這是什麼意思?那麼,因爲'tuple's是不可變的函數,*每次調用時都不能創建一個默認值,因此默認值在函數* definition *中只創建* once *。 嘗試用'def func():print(「called」)''函數來改變'someObject',看看這個函數何時被調用。 – Bakuriu

+0

這是一個很好的問題。當我來自C++時,它肯定讓我感到困惑 - 這些函數是在函數執行時評估的第二類對象,而不是函數定義。 – Shashank

回答

2

這是因爲你指定默認的參數作爲可變對象。

在python中,函數是一個對象,它在被定義時被評估,所以當你輸入def appendList(self, new = someClass())時,你定義了new作爲該函數的成員對象,並且它在執行時不會被重新評估。

看到「Least Astonishment」 in Python: The Mutable Default Argument

+0

謝謝,現在我明白髮生了什麼事。這對我來說很直觀,但我明白了。我忘了把功能當作對象。 –

相關問題