2011-06-22 39 views
28

thể trùng lặp:
“Least Astonishment” in Python: The Mutable Default Argumentthông số bắt buộc trong các chức năng Python và các giá trị mặc định của họ

tôi là loại bối rối về cách các tham số tùy chọn làm việc trong Python chức năng/phương pháp.

Tôi có khối mã sau:

>>> def F(a, b=[]): 
...  b.append(a) 
...  return b 
... 
>>> F(0) 
[0] 
>>> F(1) 
[0, 1] 
>>> 

Tại sao F(1) lợi nhuận [0, 1] và không [1]?

Ý tôi là, điều gì đang xảy ra bên trong?

+0

bạn có thể thấy một cách dễ dàng chỉ bằng cách in giá trị của b trước phụ vào danh sách. :) – sam

Trả lời

38

Tài liệu hay từ PyCon vài năm trước - Default parameter values explained. Nhưng về cơ bản, vì các danh sách là các đối tượng có thể thay đổi và các đối số từ khóa được đánh giá tại thời gian định nghĩa hàm, mỗi khi bạn gọi hàm, bạn sẽ nhận được cùng một giá trị mặc định.

Cách đúng để làm điều này sẽ là:

def F(a, b=None): 
    if b is None: 
     b = [] 
    b.append(a) 
    return b 
8

Default parameters là, khá trực giác, hơi giống như biến thành viên trên đối tượng chức năng.

Giá trị tham số mặc định được đánh giá khi định nghĩa hàm được thực hiện. Điều này có nghĩa là biểu thức được đánh giá một lần, khi hàm được xác định và giá trị "được tính trước" đó được sử dụng cho mỗi cuộc gọi. Điều này đặc biệt quan trọng để hiểu khi tham số mặc định là đối tượng có thể thay đổi, chẳng hạn như danh sách hoặc từ điển: nếu hàm sửa đổi đối tượng (ví dụ: bằng cách thêm mục vào danh sách), giá trị mặc định sẽ được sửa đổi.

http://docs.python.org/reference/compound_stmts.html#function

Danh sách là một đối tượng có thể thay đổi; bạn có thể thay đổi nội dung của họ. Các cách chính xác để có được một danh sách mặc định (hoặc từ điển, hoặc thiết lập) là để tạo ra nó vào thời gian chạy thay vào đó, bên trong hàm:

def good_append(new_item, a_list=None): 
    if a_list is None: 
     a_list = [] 
    a_list.append(new_item) 
    return a_list 
Các vấn đề liên quan