Source From Here
Question
Check sample code below:
__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:
In your example above, you'd use:
Then, when someone wanted to use your class, they'd do the following:
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:
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:
Supplement
* Python 建構、初始與消滅
Question
Check sample code below:
- class Package:
- def __init__(self):
- self.files = []
- # ...
- def __del__(self):
- for file in self.files:
- os.unlink(file)
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)
- 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)
- with Package() as package_obj:
- # use package_obj
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)
- >>> 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...
* Python 建構、初始與消滅
沒有留言:
張貼留言