Why del has to be a Python builtin

April 14, 2006

A posting today to the LiveJournal python_dev community wound up sort of asking why del has to be a Python builtin instead of a method. At first I thought this had a nice simple answer, but the more I thought about it the less obvious it became, and by the time I'd worked out a satisfying answer I'd had to really think about how Python fits together.

The short summary is that del needs to be a builtin because Python's object model is based on references and namespaces, and Python doesn't have a way to refer to your current namespaces (they have no explicit name).

Unlike in some languages, del does not literally delete objects; instead it removes references to them (which may as a side effect delete the object). In other words, del is not an object manipulation operation, it is a namespace manipulation operation. So the correct translation of 'del d' to a method call version cannot be 'd.delete()'; it has to be 'namespace.delete("d")'. But Python provides no magic namespace name for you to use for this operation, because del finds it implicitly. (Compound cases give the namespace; 'del d.c' is explicitly operating on d's namespace and duly translates to d.__delattr__("c").)

There are at least three such anonymous Python namespaces: globals, function locals (including closures), and the namespace of a class as it is being built. Of these, only the global namespace is really accessible; the latter two can only be gotten with magic, and even then you can't use __delattr__ on them. del itself does internal interpreter magic to make it all go.

(Note that locals() is explicitly not a reference to the function's namespace; it is a dictionary copy of the function's current namespace. This is because functions don't implement their namespaces using Python dictionaries. Even for things that do implement their namespace using a Python dict, it's best considered an implementation detail.)

Sidebar: all but deleting yourself

While an object cannot literally delete itself in Python, it can try real hard, by scrubbing its __dict__ and changing its __class__ to something that does nothing. (Unfortunately you can't set your __class__ to plain object, as far as I can tell; you'll need to make an actual do-nothing class.)

Written on 14 April 2006.
« An obnoxious RSS feed trick
Public interfaces and Solaris 9 patchadd exit codes »

Page tools: View Source, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Fri Apr 14 03:16:38 2006
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.