2011-11-20 36 views
5
class ToBeDeleted: 
    def __init__(self, value): 
     self.value = val 

    # Whatever... 

    def __del__(self): 
     print self.value 

l = [ToBeDeleted(i) for i in range(3)] 
del l 

In này 2, 1, 0.Gọi 'del' trên danh sách


  • Bây giờ, được thứ tự của các yếu tố xóa được định nghĩa ở đâu đó trong đặc điểm kỹ thuật hoặc là nó thực hiện cụ thể? (hoặc có thể tôi không hiểu cơ chế cơ bản)

  • Đầu ra, ví dụ: 0, 1, 2? Tôi nhận ra rằng lệnh 2, 1, 0 có thể được thực hiện để tránh việc tái phân bổ bộ nhớ cho các phần tử trong khi xóa chúng, nhưng vẫn còn câu hỏi.

  • Và điều cuối cùng - sự khác nhau giữa câu hỏi del ldel l[:] là gì?

+3

Rất nhiều nghi ngờ rằng thứ tự của các cuộc gọi cho '__del __()' được quy định bất cứ nơi nào. Thậm chí không nghĩ đến việc cố gắng viết mã dựa trên một thứ tự cụ thể. –

+0

Ngay cả khi lệnh được chỉ định, bạn có thể giữ tham chiếu đến danh sách các phần tử ở bất kỳ đâu, do đó thứ tự mà phương thức '__del__' của bạn được gọi sẽ khác với thứ tự mà tham chiếu được xóa khỏi danh sách. – millimoose

Trả lời

8

Chạy del l sẽ loại bỏ bất kỳ tài liệu tham khảo vào danh sách, vì vậy biểu tượng l sẽ biến mất. Ngược lại, việc chạy del l[:] sẽ xóa nội dung của danh sách, để l làm danh sách trống.

Phương pháp __del__ là những gì chạy khi tham chiếu cuối cùng đến một thể hiện đang bị hủy.

Thứ tự xóa không được chỉ định và thực hiện cụ thể. Khi bạn chạy del l, điều duy nhất được đảm bảo là số lượng tham chiếu cho danh sách l và mỗi phần tử của nó sẽ giảm một.

Với pypy, không có gì khác sẽ xảy ra cho đến khi bộ thu gom rác chạy. Thứ tự của việc loại bỏ đối tượng phụ thuộc vào thứ tự mà GC truy cập các đối tượng.

Trong cpython, OP đúng khi quan sát thấy việc giảm tham chiếu xảy ra từ phải sang trái. Khi gọi del l[:] ở đây là mã được sử dụng để giảm số lần truy cập: http://hg.python.org/cpython/file/2.7/Objects/listobject.c#l700. Khi số del l được gọi, mã tương tự được sử dụng để giảm số lần refcounts: http://hg.python.org/cpython/file/2.7/Objects/listobject.c#l596

+1

Cảm ơn bạn. Nhưng những gì về thứ tự của các yếu tố đã xóa? –

1
  • Lệnh xóa được thực hiện cụ thể.
  • Mỗi câu trả lời cho điểm đầu tiên, có nó có thể xóa nó theo một thứ tự khác (ngay cả các phần tử đầu tiên, ngẫu nhiên, bất cứ điều gì), và tránh reallocations có ít để làm với nó. Nó chỉ là vấn đề làm thế nào việc thực hiện lựa chọn để đi bộ trẻ em. Có lẽ bộ cấp phát bộ nhớ là hạnh phúc hơn nếu thứ tự giải phóng đảo ngược thứ tự phân bổ; nhưng đó chỉ là một phỏng đoán.
  • del l xóa chính biến đó (và do đó danh sách, nếu không có gì khác giữ nó), trong khi del l[:] xóa tất cả các phần tử khỏi danh sách. Hãy thử del l; print l.
2

Những người khác đã trả lời. Tôi sẽ chỉ thêm những gì tôi tìm thấy trong các nguồn CPython.

Các list_dealloc chức năng trong listobject.c tập tin chứa nhận xét này ngay trước khi vòng lặp trên danh sách các mục để giảm giá trị đếm tham khảo của họ:

/* Do it backwards, for Christian Tismer. 
     There's a simple test case where somehow this reduces 
     thrashing when a *very* large list is created and 
     immediately deleted. */ 
+0

Tìm thấy tuyệt vời! Đây cũng là bằng chứng khá mạnh mẽ rằng lệnh xóa là không xác định và có thể không bao giờ được. – millimoose

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