Source From Here Question Check sample code below:
- class Package:
- def __init__(self):
- self.files = []
-
- # ...
-
- def __del__(self):
- for file in self.files:
- os.unlink(file)
__del__(self) above fails with an
AttributeError exception. I understand
Python doesn't guarantee the existence of "global variables" (
member data in this context?) when
__del__() is invoked. If that is the case and this is the reason for the exception, how do I make sure the object destructs properly?
How-To I'd recommend using Python's
with statement for managing resources that need to be cleaned up. The problem with using an explicit
close() statement is that you have to worry about people forgetting to call it at all or forgetting to place it in a finally block to prevent a resource leak when an exception occurs. To use the with statement, create a class with the following methods:
- def __enter__(self)
- def __exit__(self, exc_type, exc_value, traceback)
In your example above, you'd use:
- class Package:
- def __init__(self):
- self.files = []
-
- def __enter__(self):
- return self
-
- # ...
-
- def __exit__(self, exc_type, exc_value, traceback):
- for file in self.files:
- os.unlink(file)
Then, when someone wanted to use your class, they'd do the following:
- with Package() as package_obj:
- # use package_obj
The variable
package_obj will be an instance of type
Package (
it's the value returned by the __enter__ method). Its
__exit__ method will automatically be called, regardless of whether or not an exception occurs.
Another approach is to use
atexit.register. For example:
- # package.py
- import atexit
- import os
-
- class Package:
- def __init__(self):
- self.files = []
- atexit.register(self.cleanup)
-
- def cleanup(self):
- print("Running cleanup...")
- for file in self.files:
- print("Unlinking file: {}".format(file))
- # os.unlink(file)
But you should keep in mind that this will persist all created instances of
Package until Python is terminated. Demo using the code above saved as
package.py:
- >>> from package import *
- >>> p = Package()
- >>> q = Package()
- >>> q.files = ['a', 'b', 'c']
- >>> quit()
- Running cleanup...
- Unlinking file: a
- Unlinking file: b
- Unlinking file: c
- Running cleanup...
Supplement *
Python 建構、初始與消滅
如果要定義物件被垃圾收集(Garbage collection)時,所要進行的資源清除動作,則可以定義__del__()方法,物件會被資源回收的資格,基本上就是參考至物件的變數計數為0的時候...