When is del useful in Python?
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.
Comments
-
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 assignNone
to it. And when deleting from a dictionary, adel
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?