Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python 'with' not deleting object

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
like image 739
rikkitikkitumbo Avatar asked Mar 15 '16 04:03

rikkitikkitumbo


People also ask

Do I need to delete objects in Python?

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.

How do you destroy an instance of an object in Python?

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.

How do you clear an object in Python?

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.

What is __ delete __ in Python?

__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.


1 Answers

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.

like image 68
Alex Taylor Avatar answered Oct 11 '22 18:10

Alex Taylor