Is The Del Statement Always 100% The Same As Calling __delitem__?
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.
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))
.
Like
__setattr__()
but for attribute deletion instead of assignment. This should only be implemented ifdel 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__?"