Skip to content Skip to sidebar Skip to footer

Is The Del Statement Always 100% The Same As Calling __delitem__?

a= something iterable object in python del a[1] Is del a[1] always the same as a.__delitem__(1)? Is the Python del statement defined as a call to the __delitem__ method?

Solution 1:

The del statement works on any target list, which includes subscriptions (del spam[1]) and slicings (del spam[:3]), but also attributions (del spam.eggs) and identifiers (del spam). And it does different things in each case.

The documentation for the statement maybe doesn't do a great job explaining how each of these cases work, but the Data Model chapter fills in some of the gaps.


__delitem__(self, key):

Called to implement deletion of self[key].

This includes slicings, of course; if you del spam[:3], it will call spam.__delitem__(slice(None, 3)).


__delattr__(self, name):

Like __setattr__() but for attribute deletion instead of assignment. This should only be implemented if del obj.name is meaningful for the object.


In theory, a __getattribute__ on the class or metaclass could reroute these calls. But since both of these calls are done via special method lookup, Python is allowed to look the methods up directly, and, at least in CPython 3.7 and 2.7, it does. So, __delitem__ or __delattr__ will always be called.


For identifiers, what happens depends on whether the compiler identifies the variable as a local, nonlocal, or global. This uses the same rules as any other variable reference.

For globals, this effectively means del globals()['spam']. For locals, it's sort of like del locals()['spam'], except that it actually affects the local environment. For nonlocals, it essentially calls a delete_contents() function on the closure cell.


It may help to use the dis module to see how CPython compiles the different forms of the del statement, and then look up what each of the bytecodes does. Of course that's specific to CPython, but it demonstrates what any Python implementation needs to do, however it chooses to do it.


1. But notice that deletion counts as a binding operation, just like assignment does. So, unless spam is declared global or nonlocal (or the code is at the top level), del spam is going to make spam local.

2. Then again, if you don't know anything about bytecode, fast locals, etc., it probably won't help very much…

Post a Comment for "Is The Del Statement Always 100% The Same As Calling __delitem__?"