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?
I’d recommend using Python’s
withstatement for managing resources that need to be cleaned up. The problem with using an explicitclose()statement is that you have to worry about people forgetting to call it at all or forgetting to place it in afinallyblock to prevent a resource leak when an exception occurs.To use the
withstatement, 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.You could even take this approach a step further. In the example above, someone could still instantiate Package using its constructor without using the
withclause. You don’t want that to happen. You can fix this by creating a PackageResource class that defines the__enter__and__exit__methods. Then, the Package class would be defined strictly inside the__enter__method and returned. That way, the caller never could instantiate the Package class without using awithstatement:You’d use this as follows: