When is del useful in Python?

363,796

Solution 1

Firstly, you can del other things besides local variables

del list_item[4]
del dictionary["alpha"]

Both of which should be clearly useful. Secondly, using del on a local variable makes the intent clearer. Compare:

del foo

to

foo = None

I know in the case of del foo that the intent is to remove the variable from scope. It's not clear that foo = None is doing that. If somebody just assigned foo = None I might think it was dead code. But I instantly know what somebody who codes del foo was trying to do.

Solution 2

There's this part of what del does (from the Python Language Reference):

Deletion of a name removes the binding of that name from the local or global namespace

Assigning None to a name does not remove the binding of the name from the namespace.

(I suppose there could be some debate about whether removing a name binding is actually useful, but that's another question.)

Solution 3

One place I've found del useful is cleaning up extraneous variables in for loops:

for x in some_list:
  do(x)
del x

Now you can be sure that x will be undefined if you use it outside the for loop.

Solution 4

Deleting a variable is different than setting it to None

Deleting variable names with del is probably something used rarely, but it is something that could not trivially be achieved without a keyword. If you can create a variable name by writing a=1, it is nice that you can theoretically undo this by deleting a.

It can make debugging easier in some cases as trying to access a deleted variable will raise an NameError.

You can delete class instance attributes

Python lets you write something like:

class A(object):
    def set_a(self, a):
        self.a=a
a=A()
a.set_a(3)
if hasattr(a, "a"):
    print("Hallo")

If you choose to dynamically add attributes to a class instance, you certainly want to be able to undo it by writing

del a.a

Solution 5

There is a specific example of when you should use del (there may be others, but I know about this one off hand) when you are using sys.exc_info() to inspect an exception. This function returns a tuple, the type of exception that was raised, the message, and a traceback.

The first two values are usually sufficient to diagnose an error and act on it, but the third contains the entire call stack between where the exception was raised and where the the exception is caught. In particular, if you do something like

try:
    do_evil()
except:
    exc_type, exc_value, tb = sys.exc_info()
    if something(exc_value):
        raise

the traceback, tb ends up in the locals of the call stack, creating a circular reference that cannot be garbage collected. Thus, it is important to do:

try:
    do_evil()
except:
    exc_type, exc_value, tb = sys.exc_info()
    del tb
    if something(exc_value):
        raise

to break the circular reference. In many cases where you would want to call sys.exc_info(), like with metaclass magic, the traceback is useful, so you have to make sure that you clean it up before you can possibly leave the exception handler. If you don't need the traceback, you should delete it immediately, or just do:

exc_type, exc_value = sys.exc_info()[:2]

To avoid it all together.

Share:
363,796
Jason Baker
Author by

Jason Baker

I'm a developer on Google's Cloud Console.

Updated on November 09, 2021

Comments

  • Jason Baker
    Jason Baker over 2 years

    I can't really think of any reason why Python needs the del keyword (and most languages seem to not have a similar keyword). For instance, rather than deleting a variable, one could just assign None to it. And when deleting from a dictionary, a del method could be added.

    Is there a reason to keep del in Python, or is it a vestige of Python's pre-garbage collection days?