Trying to properly delete a Python object. I'm creating an object and then supposedly deleting it with a 'with' statement. But when I do a print out after the 'with' statement is closed.... the object is still there:
class Things(object):
def __init__(self, clothes, food, money):
self.clothes = clothes
self.food = food
self.money = money
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print('object deleted')
with Things('socks','food',12) as stuff:
greg = stuff.clothes
print(greg)
print(stuff.clothes)
returns :
socks
object deleted
socks
1) Yes, I would recommend deleting the object. This will keep your code from getting bulky and/or slow. This is an especially good decision if you have a long run-time for your code, even though Python is pretty good about garbage collection.
Using the __del__() method. In Python, a destructor is defined using the specific function __del__(). For instance, when we run del object name, the object's destructor is automatically called, and it then gets garbage collected.
The del keyword in python is primarily used to delete objects in Python. Since everything in python represents an object in one way or another, The del keyword can also be used to delete a list, slice a list, delete a dictionaries, remove key-value pairs from a dictionary, delete variables, etc.
__del__ in Python __del__ is a reserved function in Python that is called when the last reference to an object is being deleted or goes out of scope. It is similar to the destructor of C++ and is also known as the finalizer.
Python's with
statement is not about deleting objects - it's about resource management. The __enter__
and __exit__
methods are for you to supply resource initialization and destruction code i.e. you may choose to delete something there, but there is no implicit deletion of objects. Have a read of this with
article to get a better understanding of how to use it.
The object stays in scope after the with
statement. You could call del
on it if that's what you want. Since it's in scope you can query it after it's underlying resources have been closed. Consider this psuedo code:
class DatabaseConnection(object):
def __init__(self, connection):
self.connection = connection
self.error = None
def __enter__(self):
self.connection.connect()
def __exit__(self, exc_type, exc_val, exc_tb):
self.connection.disconnect()
def execute(self, query):
try
self.connection.execute(query)
except e:
self.error = e
with DatabaseConnection(connection) as db:
db.execute('SELECT * FROM DB')
if db.error:
print(db.error)
del db
We wouldn't want to keep a database connection hanging around longer than we need (another thread/client might need it), so instead we allow the resource to be freed (implicitly at the end of the with
block), but then we can continue to query the object after that. I've then added an explicit del
to tell the runtime that the code is finished with the variable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With