I'm not sure where this comment belongs, but I want to share my perspective on the documentation of these special method names. In the following section there is an inconsistency which could be confusing to someone just learning Python (e.g., me).

In the sentence on implementing custom mapping objects, the recommended method names are listed as the short calling names: eys(), values(), items(), etc.

But, in contrast, in the sentence on implementing sequence types, the recommended method names are listed as the double underscore internal implementation names: __add__(), __radd__(), __iadd__(), __mul__(), etc.

Here's the section of the documentation with this inconsistency. I think it would help to use one or the other of these pairs (calling name vs. internal implementation name) consistently in this section.

3.4.6. Emulating container types

The following methods can be defined to implement container objects. Containers usually are sequences (such as lists or tuples) or mappings (like dictionaries), but can represent other containers as well. The first set of methods is used either to emulate a sequence or to emulate a mapping; the difference is that for a sequence, the allowable keys should be the integers k for which 0 <= k < N where N is the length of the sequence, or slice objects, which define a range of items. (For backwards compatibility, the method __getslice__() (see below) can also be defined to handle simple, but not extended slices.) It is also recommended that mappings provide the methods keys(), values(), items(), has_key(), get(), clear(), setdefault(), iterkeys(), itervalues(), iteritems(), pop(), popitem(), copy(), and update() behaving similar to those for Python’s standard dictionary objects. The UserDict module provides a DictMixin class to help create those methods from a base set of __getitem__(), __setitem__(), __delitem__(), and keys(). Mutable sequences should provide methods append(), count(), index(), extend(), insert(), pop(), remove(), reverse() and sort(), like Python standard list objects. Finally, sequence types should implement addition (meaning concatenation) and multiplication (meaning repetition) by defining the methods __add__(), __radd__(), __iadd__(), __mul__(), __rmul__() and __imul__() described below; they should not define __coerce__() or other numerical operators. It is recommended that both mappings and sequences implement the __contains__() method to allow efficient use of the in operator; for mappings, in should be equivalent of has_key(); for sequences, it should search through the values. It is further recommended that both mappings and sequences implement the __iter__() method to allow efficient iteration through the container; for mappings, __iter__() should be the same as iterkeys(); for sequences, it should iterate through the values.

This is in addition to some missing documentation regarding mention how some of the special method names should be conveniently called in code. (See below.)


On Wed, Jun 6, 2012 at 3:59 PM, Dave <davestechshop@gmail.com> wrote:


On Wed, Jun 6, 2012 at 3:40 PM, Mark Lawrence <breamoreboy@yahoo.co.uk> wrote:
On 06/06/2012 20:19, Dave wrote:
I was reading some tutorial material on creating iterators. It shows the
following example implementation of an iterator:

class Reverse:
    """Iterator for looping over a sequence backwards."""
    def __init__(self, data):
        self.data = data
        self.index = len(data)
    def __iter__(self):
        return self
    def next(self):
        if self.index == 0:
            raise StopIteration
        self.index = self.index - 1
        return self.data[self.index]


My question is how was I supposed to kinow that the function I call using
the name iter() is implemented using the name __iter__()?

Is there a rule that describes when I would implement an attribute name
with leading and trailing double underscores, and then call it without
those underscores? How many names like this exist in Python? Are these
special cases or is there a general rule that leading and trailing double
underscores get dropped when calling functions that were implemented with
these names? I'm trying to understand the big picture as far as how Python
works when it comes to this situation. Thanks.


Try this to start with http://docs.python.org/reference/datamodel.html#special-method-names. Note this is for Python 2.7.3, there may be differences in Python 3.x.

--

Actually, I think I'm getting it now... as I read more of this page I see that there is no single generalization. These are indeed all special cases.

But the documentation does appear to be incomplete. It leaves out the mapping to the name or symbol that should be used to call the special function in some cases. In particular, in the case of __iter(self), which is one of the first ones I looked at, it doesn't mention that this is usually called via iter(). It does mention how it would be called for mapping containers, however (i.e., iterkeys()).
object.__iter__(self)

This method is called when an iterator is required for a container. This method should return a new iterator object that can iterate over all the objects in the container. For mappings, it should iterate over the keys of the container, and should also be made available as the method iterkeys().

But as I read more, I see that much of the documentation does mention how these special method names are called. For example:

object.__lt__(self, other)
object.__le__(self, other)
object.__eq__(self, other)
object.__ne__(self, other)
object.__gt__(self, other)
object.__ge__(self, other)

New in version 2.1.

These are the so-called “rich comparison” methods, and are called for comparison operators in preference to __cmp__() below. The correspondence between operator symbols and method names is as follows: x<y calls x.__lt__(y), x<=y calls x.__le__(y), x==y calls x.__eq__(y), x!=y and x<>y call x.__ne__(y), x>y calls x.__gt__(y), and x>=y calls x.__ge__(y).

I think there is enough info at this page to answer my question as well as I need it answered right now. Thanks.