Python协议/接口的综合列表

19

最近,我在研究一些Python习语。 我发现很多关于Python中使用的协议的描述,如排序(__cmp__, ...)或生成器。此外,还有像__hash__这样的方法,它们被定义为每个对象(我想)。

在互联网上进行了一些搜索后,我没有找到一个包含这些协议和方法的全面列表。 有人能给我一些指针URL吗?


10
好的,这是一个漫画网站xkcd的链接,题目是“对不起”(Sorry)。 - johnsyweb
1
FYI,它们通常被称为“魔术方法”。 - Katriel
可能是Python中的特殊(魔术)方法的重复问题。 - Katriel
2个回答

16

你最好的参考资料始终是Python在线文档,特别是关于特殊方法名的部分。

交互式Python解释器也是一个非常有用的工具。尝试一些这样的操作:

>>> 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)

10

更新:此函数现在将遍历对象的子类链并提取所有的抽象方法。要使用旧行为,请设置nested=False

按照惯例,协议是描述共同行为的一组特殊方法。您可以从{{link1:collections.abc}}模块(Python 3.3+)的抽象方法中大致推断出协议;也可参阅文档。以下是自动化生成此列表的方法:

给定

import abc

import collections as ct

代码

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)

演示

get_protocols()

输出

{
 '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__'}
}

注意:当进行子类化时,这些是(必需的)抽象方法,不包括混合方法。例如:对collections.abc.Mappings进行子类化将提供方法.keys().values().items()(未列出),一旦实现了协议。

注意:仅列出抽象方法。某些方法被排除在外,例如所有类似生成器的函数上的close()


1
一份如此独特有用的答案,值得收藏。 - odigity

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接