2013-03-14 15 views
8

Tôi hiểu rằng Python không đảm bảo thứ tự hủy diệt các đối tượng ở cuối chương trình, hoặc thậm chí là nó sẽ xảy ra.Tại sao Python phá hủy các biến lớp trước đối tượng?

Vì vậy, tôi hiểu rằng trình phá hủy của lớp không thể dựa vào các biến toàn cầu, bao gồm cả các mô-đun khác.

Nhưng tôi đã nghĩ rằng các vật thể của lớp sẽ phải bị phá hủy trước khi lớp học bị phá hủy. Rõ ràng không:

class A(object): 
    count = 0 
    def __init__(self): 
     A.count += 1 
     print 'Creating object, there are now', A.count 
    def __del__(self): 
     A.count -= 1 
     print 'Destroying object, there are now', A.count 

a1 = A() 
a2 = A() 

Trên Windows 7 x64 Python v2.7.3 tôi nhận được:

Creating object, there are now 1 
Creating object, there are now 2 
Exception AttributeError: "'NoneType' object has no attribute 'count'" in <bound 
method A.__del__ of <__main__.A object at 0x0234B8B0>> ignored 
Exception AttributeError: "'NoneType' object has no attribute 'count'" in <bound 
method A.__del__ of <__main__.A object at 0x0234BE90>> ignored 

Tôi hiểu ý nghĩa của How do I correctly clean up a Python object?. Nhưng trường hợp này là dành cho lớp (chia sẻ hoặc 'tĩnh' cho các biến C++ bạn bè của tôi). Chắc chắn trường hợp có một tham chiếu đến biến lớp, mà không nên bị phá hủy đầu tiên vì chúng ta vẫn có một tham chiếu đến nó?

Có vấn đề hay sai lầm khi lớp học bị hủy trước các đối tượng của lớp đó? Có lẽ câu hỏi của tôi là 'đâu biến đẳng cấp chia sẻ thực sự được lưu trữ "

(Vâng, tôi hiểu rằng điều này có thể được sửa chữa bằng cách sử dụng quản lý nội dung, hoặc thậm chí chỉ đơn giản là:

del a1 
del a2 

để tiêu diệt các đối tượng trước lớp bị phá hủy.)

Trả lời

6

Maybe my question is 'Where are class-shared variables actually stored?"

Nếu đó là câu hỏi của bạn, câu trả lời là "trên lớp".

Để giải quyết lar của bạn Câu hỏi ger: Như bạn đã lưu ý, __del__ không thể dựa vào các biến toàn cầu --- nhưng A là một biến toàn cục, vì vậy bạn không thể dựa vào nó. Thật thú vị, tôi không thể tìm thấy một tuyên bố chính thức về điều này trong tài liệu, nhưng có nhiều tài liệu tham khảo khác nhau trên internet để thực tế này là __del__ không thể sử dụng các biến toàn cầu. Here là một:

When a Python program terminates the global variables in each module are set to None. The order in which this happens it undefined

Nó sẽ có tác dụng nếu bạn truy cập vào các tính qua self.__class__.count thay vì A.count. (Đây cũng là lý do tại sao nó hoạt động khi bạn sử dụng self.count.)

+1

điều gì về '.__ class__' trên cá thể? – FatalError

+1

@ FatalError: Bạn nói đúng, vấn đề tham chiếu là cá trích đỏ. Vấn đề không phải là chính lớp đã bị xóa, nhưng biến toàn cục tham chiếu nó đã được đặt thành Không. Tôi đã chỉnh sửa câu trả lời của mình. – BrenBarn

+2

Thật kỳ lạ, tôi nhận được cùng một hành vi khi tôi thử nó với '.__ class__'. Có vẻ như nó cũng được đặt thành 'None' trước khi gọi' __del__' trong trường hợp này, điều này thật đáng ngạc nhiên. – FatalError