2013-09-05 64 views
6

Tôi có một vấn đề nhỏ mà tôi không hiểu.Python - tại sao nó không tạo ra một thể hiện đối tượng mới?

Tôi có một phương pháp:

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

tôi gọi phương pháp này mà không có thuộc tính:

object.appendMethod() 

Và thực sự tôi thêm danh sách với cùng một ví dụ của someObject.

Nhưng nếu tôi thay đổi nó thành:

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

tôi nhận được thể hiện mới của đối tượng mà mọi thời gian, sự khác biệt là gì?

Dưới đây là một ví dụ:

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

câu hỏi này được không * đúng * liên quan đến giá trị mặc định có thể thay đổi, nhưng là về * khi * giá trị mặc định được tạo ra. @tomek lưu ý rằng mọi hàm giữ một ** 'tuple' ** của các giá trị mặc định của nó trong thuộc tính' __defaults__'. Nhưng cái đó nghĩa là gì? Vâng, chắc chắn vì 'tuple' là các hàm bất biến * không thể * tạo ra một giá trị mặc định mỗi khi chúng được gọi, do đó giá trị mặc định chỉ được tạo * một lần * ở hàm * định nghĩa *. Cố gắng thay đổi 'someObject' bằng một hàm như' def func(): print ("được gọi là") 'và xem khi hàm này được gọi. – Bakuriu

+0

Đây là một câu hỏi hay. Nó chắc chắn làm tôi bối rối khi tôi đến từ C++ - nơi mà các hàm là các đối tượng hạng hai được đánh giá tại thực thi hàm chứ không phải là định nghĩa hàm. – Shashank

Trả lời

2

Điều này là do bạn đang gán tham số mặc định của bạn như một đối tượng có thể thay đổi.

Trong python, hàm là đối tượng được đánh giá khi được xác định, khi bạn nhập def appendList(self, new = someClass()), bạn xác định new làm đối tượng thành viên của hàm và không được đánh giá lại vào thời gian thực thi.

thấy “Least Astonishment” in Python: The Mutable Default Argument

+0

cảm ơn bạn, bây giờ tôi hiểu điều gì xảy ra. Nó phản trực giác với tôi, nhưng tôi hiểu rồi. Tôi quên nghĩ về các chức năng như các đối tượng. –