2012-03-27 37 views
7

thể trùng lặp:
“Least Astonishment” in Python: The Mutable Default ArgumentGiá trị của một danh sách trống trong tham số chức năng, ví dụ ở đây

def f(a, L=[]): 
    L.append(a) 
    return L 

print(f(1, [1, 2])) 
print(f(1)) 
print(f(2)) 
print(f(3)) 

Tôi tự hỏi tại sao e khác (1), f (2) , f (3) không nối thêm f đầu tiên (1, [1,2]). Tôi đoán kết quả phải là:

[1, 2, 1] 
[1, 2, 1, 1] 
[1, 2, 1, 1, 2] 
[1, 2, 1, 1, 2, 3] 

Nhưng kết quả không phải như vậy. Tôi không biết tại sao.

+1

@Closevoters: như là hiển nhiên từ ví dụ của mình, anh ta mong đợi đối số mặc định để thay đổi, do đó, không, không phải là một bản sao nào. – georg

Trả lời

6

Có hai vấn đề khác nhau (tốt hơn để gọi là khái niệm) hợp nhất thành một tuyên bố vấn đề.

Đầu tiên có liên quan đến câu hỏi SO như được chỉ định bởi agh. Luồng này đưa ra một lời giải thích chi tiết và sẽ không có ý nghĩa gì trong việc giải thích nó một lần nữa ngoại trừ vì chủ đề này, tôi chỉ có thể nói rằng các hàm là các đối tượng lớp đầu tiên và các tham số và giá trị mặc định của chúng được giới hạn trong quá trình khai báo. Vì vậy, các tham số hoạt động giống như các tham số tĩnh của một hàm (nếu một cái gì đó có thể được thực hiện bằng các ngôn ngữ khác mà không hỗ trợ các đối tượng hàm lớp đầu tiên

Vấn đề thứ hai là đối tượng danh sách tham số L bị ràng buộc. Khi được gọi mà không có tham số nào thì nó giống như liên kết với một danh sách khác (danh sách được nhắc đến như là tham số mặc định) mà tham số sẽ khác với những gì được thông qua Trong cuộc gọi đầu tiên, để làm cho trường hợp nổi bật hơn, chỉ cần thay đổi chức năng của bạn như sau và chạy các mẫu.

>>> def f(a, L=[]): 
     L.append(a) 
     print id(L) 
     return L 

>>> print(f(1, [1, 2])) 
56512064 
[1, 2, 1] 
>>> print(f(1)) 
51251080 
[1] 
>>> print(f(2)) 
51251080 
[1, 2] 
>>> print(f(3)) 
51251080 
[1, 2, 3] 
>>> 

Như bạn thấy, đầu tiên tất cả in một id khác nhau của tham số L tương phản với các cuộc gọi tiếp theo. Vì vậy, nếu các danh sách khác nhau, do đó sẽ là hành vi và nơi giá trị được thêm vào. Hy vọng rằng bây giờ nó sẽ có ý nghĩa

+0

Cảm ơn tất cả các bạn, tôi hiểu nó ngay bây giờ. rất tốt. – stardiviner

0

Tại sao bạn chờ kết quả đó nếu bạn gọi hàm khởi tạo danh sách trống nếu bạn không vượt qua đối số thứ hai?

Đối với những kết quả mà bạn muốn, bạn nên sử dụng đóng hoặc var toàn cầu.

Các vấn đề liên quan