Double underscore names
steven.bethard at gmail.com
Wed Feb 13 05:17:14 CET 2008
Steven D'Aprano wrote:
> Double-underscore names and methods are special to Python. Developers are
> prohibited from creating their own (although the language doesn't enforce
> that prohibition). From PEP 0008, written by Guido himself:
> __double_leading_and_trailing_underscore__: "magic" objects or
> attributes that live in user-controlled namespaces. E.g. __init__,
> __import__ or __file__. Never invent such names; only use them
> as documented.
> But then there are modules like doctest, which uses the special double-
> underscore name __test__.
> There are times where I would like to create my own protocol, like the
> early sequence protocol: if an object has a __getitem__ method, it can be
> used with for loops. Python calls obj.__getitem__(i) with i starting at 0
> and increasing by one each time until it gets an IndexError exception.
> This sequence protocol has been made partly obsolete by the iterator
> protocol, but you see the point: in the spirit of duck typing, having the
> ability to create a protocol is a Very Good Thing, and double leading and
> trailing underscore names are the accepted Python style for such special
> But the style guide says not to do that.
> So I find myself conflicted. I'm aware that the style guide also says,
> know when to break the rules, but the examples given don't seem to apply
> to this case. The prohibition against inventing new double-underscore
> names like __parrot__ seems much stronger than the other style guides.
> So what do folks think? I believe the protocol idiom ("look for a method
> called __parrot__ and then do something with it") is too useful and
> powerful to be ignored, but then if __parrot__ is reserved by Python,
> what to do?
I've come to believe that in most cases when you want to establish a new
protocol, you'd be better off defining a generic function and
overloading it rather than using the __magic__ attribute approach. See,
for example, the simplegeneric module:
Generic functions have the advantage that when one of your users
discovers someone else's class that is missing support for your
protocol, then can add it to that class without having to edit the code
of the class (e.g. so that they can add a __magic__ attribute). Instead,
they can just register an appropriate overload for that class.
More information about the Python-list