2012-03-19 36 views
9

xem xét đoạn mã sau:hành vi khác nhau cho danh sách .__ iadd__ và danh sách .__ add__

>>> x = y = [1, 2, 3, 4] 
>>> x += [4] 
>>> x 
[1, 2, 3, 4, 4] 
>>> y 
[1, 2, 3, 4, 4] 

và sau đó xem xét việc này:

>>> x = y = [1, 2, 3, 4] 
>>> x = x + [4] 
>>> x 
[1, 2, 3, 4, 4] 
>>> y 
[1, 2, 3, 4] 

Tại sao lại có một sự khác biệt hai?

(Và có, tôi đã thử tìm kiếm điều này).

+4

Điều thú vị về câu lệnh cuối cùng của bạn, là chức năng này thực sự được giải thích trong tài liệu python: http://docs.python.org/reference/datamodel.html#object.__add__ (từ tìm kiếm về các điều khoản đó) – jdi

+3

@jdl: Có, tôi thừa nhận rằng tôi đã bỏ qua điều đó. –

Trả lời

20

__iadd__ thay đổi danh sách, trong khi __add__ trả về danh sách mới, như được minh họa.

Biểu thức x += y đầu tiên cố gắng gọi __iadd__ và, nếu không, hãy gọi __add__ theo sau một bài tập (xem nhận xét của Sven về chỉnh sửa nhỏ). Kể từ khi list__iadd__ thì nó thực hiện một chút phép thuật đột biến này.

+1

Nếu bạn muốn biết thêm chi tiết về hành vi chính xác này và những hiểu biết khác về lý do tại sao Python là cách nó - Tôi rất muốn giới thiệu [python epiphanies talk] (http://pyvideo.org/video/613/python-epiphanies) từ PyCon 2012. Nó sẽ dẫn bạn đến rất nhiều 'một ha!' khoảnh khắc. –

+0

@S Singh nếu bạn nhận được câu trả lời của bạn thì vui lòng chọn câu trả lời là câu trả lời được chấp nhận và hoàn thành quy trình làm việc. Nếu không câu hỏi này sẽ được hiển thị là chưa được trả lời. – Nilesh

+1

Câu trả lời này hơi gây nhầm lẫn: Việc gán luôn luôn được thực hiện, bất kể là '__iadd __()' hay '__add __()' được gọi. 'list .__ iadd __()' đơn giản trả về 'self', mặc dù vậy việc gán không có tác dụng nào khác ngoài việc hiển thị tên đích cục bộ cho phạm vi hiện tại. –

3

Danh sách thay đổi đầu tiên và danh sách thứ hai sẽ đổi tên.

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