2013-08-05 22 views
10

Tôi có một đối tượng lớp python và tôi muốn gán giá trị của một lớp biếnPython AttributeError trên __del__

class Groupclass(Workerclass): 
    """worker class""" 
    count = 0 

    def __init__(self): 
     """initialize time""" 
     Groupclass.count += 1 
     self.membercount = 0; 
     self.members = [] 

    def __del__(self): 
     """delte a worker data""" 
     Groupclass.count -= 1 


if __name__ == "__main__": 
    group1 = Groupclass() 

kết quả thực hiện này là đúng, nhưng có một thông báo lỗi nói:

Exception AttributeError: "'NoneType' object has no attribute 'count'" in <bound method Groupclass.__del__ of <__main__.Groupclass instance at 0x00BA6710>> ignored 

Ai đó có thể cho tôi biết tôi đã làm gì sai không?

+1

Lớp cơ sở 'Workerclass' dường như có phương thức' __del__' đang cố gắng làm điều gì đó với 'đếm', nhưng bạn không chia sẻ phương pháp đó tại đây. –

+0

xin lỗi tôi không biết điều đó có liên quan ... –

+0

Tin nhắn của bạn chỉ là cảnh báo, nó không phải là lỗi. ** Một cái gì đó ** trong phương thức '__del__' đã cố gắng làm điều gì đó với thuộc tính' count' và thất bại. –

Trả lời

13

Phương pháp __del__ của bạn giả định rằng lớp vẫn còn hiện diện vào thời điểm được gọi.

Giả định này không chính xác. Groupclass đã được xóa khi chương trình Python của bạn thoát và hiện được đặt thành None.

Kiểm tra nếu tham chiếu toàn cầu đến lớp vẫn còn tồn tại đầu tiên:

def __del__(self): 
    if Groupclass: 
     Groupclass.count -= 1 

hoặc sử dụng type() để có được những tài liệu tham khảo địa phương:

def __del__(self): 
    type(self).count -= 1 

nhưng lưu ý rằng điều này có nghĩa rằng ngữ nghĩa cho count thay đổi nếu Groupclass được phân loại (mỗi lớp con nhận được thuộc tính .count so với chỉ Groupclass có thuộc tính .count).

Trích dẫn từ tài liệu __del__ móc:

Warning: Do các trường hợp bấp bênh theo đó __del__() phương pháp được gọi, trường hợp ngoại lệ xảy ra trong khi thực hiện của họ sẽ được bỏ qua, và một cảnh báo được in để sys.stderr thay . Ngoài ra, khi __del__() được gọi để đáp ứng với một mô-đun bị xóa (ví dụ, khi thực hiện chương trình được thực hiện), các globals khác được tham chiếu theo phương pháp __del__() có thể đã bị xóa hoặc trong quá trình bị rách (ví dụ: máy móc nhập khẩu đang Tắt). Vì lý do này, các phương pháp __del__() nên thực hiện tối thiểu tuyệt đối cần thiết để duy trì các bất biến bên ngoài. Bắt đầu với phiên bản 1.5, Python đảm bảo rằng các hình cầu có tên bắt đầu bằng một dấu gạch dưới đơn sẽ bị xóa khỏi mô đun của chúng trước khi các hình cầu khác bị xóa; nếu không có các tham chiếu khác cho các hình cầu đó tồn tại, điều này có thể giúp đảm bảo rằng các mô-đun đã nhập vẫn có sẵn tại thời điểm phương thức __del__() được gọi.

Nếu bạn đang sử dụng Python 3, hai ghi chú thêm được áp dụng:

  • CPython 3.3 tự động áp dụng một randomized hash salt cho các phím str được sử dụng trong một cuốn từ điển globals; điều này cũng ảnh hưởng đến thứ tự mà các hình cầu được làm sạch và có thể là bạn chỉ gặp sự cố trên một số số số lần chạy.

  • CPython 3.4 không còn đặt hình cầu thành None (trong hầu hết các trường hợp), theo Safe Object Finalization; xem PEP 442.

+0

Cảm ơn bạn hiện đang hoạt động. Bây giờ câu hỏi của tôi là nếu tôi muốn 'del' một' Groupclass' đối tượng, 'Groupclass' đối tượng hoặc 'Groupclass' chính nó phải tồn tại trước khi' del' sẽ được thực hiện vì vậy có vẻ như tuyên bố là bằng cách nào đó dư thừa? –

+0

@Chandler: Không, khi thông dịch viên tồn tại, tên toàn cầu có thể được dọn sạch trước khi có trường hợp; tên 'Groupclass' đã được dọn sạch rồi. Bạn cũng có thể sử dụng 'loại (tự) .count' thay vào đó, trừ khi bạn có các lớp con không có số đếm riêng của chúng. –

+0

vẫn không hoàn toàn hiểu về khái niệm này nhưng cảm ơn tôi sẽ xem xét điều này! –

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