Search code examples
pythoncoding-style

Using explicit del in python on local variables


What are the best practices and recommendations for using explicit del statement in python? I understand that it is used to remove attributes or dictionary/list elements and so on, but sometimes I see it used on local variables in code like this:

def action(x):
    result = None
    something = produce_something(x)
    if something:
        qux = foo(something)
        result = bar(qux, something)
        del qux
    del something
    return result

Are there any serious reasons for writing code like this?

Edit: consider qux and something to be something "simple" without a __del__ method.


Solution

  • I don't remember when I last used del -- the need for it is rare indeed, and typically limited to such tasks as cleaning up a module's namespace after a needed import or the like.

    In particular, it's not true, as another (now-deleted) answer claimed, that

    Using del is the only way to make sure a object's __del__ method is called

    and it's very important to understand this. To help, let's make a class with a __del__ and check when it is called:

    >>> class visdel(object):
    ...   def __del__(self): print 'del', id(self)
    ... 
    >>> d = visdel()
    >>> a = list()
    >>> a.append(d)
    >>> del d
    >>>
    

    See? del doesn't "make sure" that __del__ gets called: del removes one reference, and only the removal of the last reference causes __del__ to be called. So, also:

    >>> a.append(visdel())
    >>> a[:]=[1, 2, 3]
    del 550864
    del 551184
    

    when the last reference does go away (including in ways that don't involve del, such as a slice assignment as in this case, or other rebindings of names and other slots), then __del__ gets called -- whether del was ever involved in reducing the object's references, or not, makes absolutely no difference whatsoever.

    So, unless you specifically need to clean up a namespace (typically a module's namespace, but conceivably that of a class or instance) for some specific reason, don't bother with del (it can be occasionally handy for removing an item from a container, but I've found that I'm often using the container's pop method or item or slice assignment even for that!-).