Comprehensive list of Python protocols/interfaces

Question:

Lately, I was looking at some Python idioms.
I found many descriptions of protocols used in Python, such as the ordering (__cmp__, …) or generators. Besides, there are also methods like __hash__ which are defined for every object (I suppose).

After some search on the internet, I haven’t found a comprehensive list of these protocols and methods.
Can anyone give me some pointers URLs?

Asked By: Kru

||

Answers:

Your best reference is always going to be the Python Online Documentation, specifically the section on Special method names.

The interactive Python interpretor is a very useful tool, too. Try some of these:

>>> dir(object)
['__class__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
>>> help(object.__class__)

>>> help(object.__hash__)

>>> help(hash)
Answered By: johnsyweb

UPDATE: this function will now traverse an object’s subclass chain and extract ALL abstractmethods. To use the old behavior, set nested=False.

By convention, protocols are groups of special methods that describe common behaviors. You can roughly infer protocols from the abstract methods of the collections.abc module (Python 3.3+); see also the docs. Automate this listing with the following:

Given

import abc

import collections as ct

Code

def get_protocols(source=ct.abc, nested=True):
    """Return a dict of protocols from source abstractmethods only."""
    dd = ct.defaultdict(set)

    for objname in dir(source):
        if objname.startswith("_"):
            continue

        obj = getattr(source, objname)
        classes = obj.__mro__ if nested else [obj]

        for cls in classes:
            if cls is object:
                continue
            abmethods = sorted(cls.__abstractmethods__)
            if not abmethods:
                continue    
            dd[objname] |= set(abmethods)        
    return dict(dd)

Demo

get_protocols()

Output

{
 'AsyncGenerator': {'__aiter__', '__anext__', 'asend', 'athrow'},
 'AsyncIterable': {'__aiter__'},
 'AsyncIterator': {'__aiter__', '__anext__'},
 'Awaitable': {'__await__'},
 'ByteString': {'__contains__', '__getitem__', '__iter__', '__len__', '__reversed__'},
 'Callable': {'__call__'},
 'Collection': {'__contains__', '__iter__', '__len__'},
 'Container': {'__contains__'},
 'Coroutine': {'__await__', 'send', 'throw'},
 'Generator': {'__iter__', '__next__', 'send', 'throw'},
 'Hashable': {'__hash__'},
 'ItemsView': {'__contains__', '__iter__', '__len__'},
 'Iterable': {'__iter__'},
 'Iterator': {'__iter__', '__next__'},
 'KeysView': {'__contains__', '__iter__', '__len__'},
 'Mapping': {'__contains__', '__getitem__', '__iter__', '__len__'},
 'MappingView': {'__len__'},
 'MutableMapping': {'__contains__', '__delitem__', '__getitem__', '__iter__', '__len__', '__setitem__'},
 'MutableSequence': {'__contains__', '__delitem__', '__getitem__', '__iter__', '__len__', '__reversed__', '__setitem__', 'insert'},
 'MutableSet': {'__contains__', '__iter__', '__len__', 'add', 'discard'},
 'Reversible': {'__iter__', '__reversed__'},
 'Sequence': {'__contains__', '__getitem__', '__iter__', '__len__', '__reversed__'},
 'Set': {'__contains__', '__iter__', '__len__'},
 'Sized': {'__len__'},
 'ValuesView': {'__contains__', '__iter__', '__len__'}
}

NOTE: When sub-classing, these are (required) abstract methods that do not include the mixin methods. Example: sub-classing collections.abc.Mappings will provide methods .keys(), .values(), .items() (no listed) once the protocol is implemented.

NOTE: Only abstractmethods are listed. Some methods are excluded, e.g. close() on all generator-like functions.

Answered By: pylang
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.