对于 singledispatch 中寻找最佳匹配类型有一点不解?

0
PEP 443 中提到
```Python
from functools import singledispatch

from collections import Iterable, Container
class P(object):
pass
Iterable.register(P)
Container.register(P)
@singledispatch
def g(arg):
return "base"

g.register(Iterable, lambda arg: "iterable")
g.register(Container, lambda arg: "container")
g(P())
```
这种会产生二义性,本人翻了翻 singledispatch 的实现,发现作匹配时是这样的过程
```Python
def _find_impl(cls, registry):
"""Returns the best matching implementation from *registry* for type *cls*.

Where there is no registered implementation for a specific type, its method
resolution order is used to find a more generic implementation.

Note: if *registry* does not contain an implementation for the base
*object* type, this function may return None.

"""
mro = _compose_mro(cls, registry.keys())
match = None
for t in mro:
if match is not None:
# If *match* is an implicit ABC but there is another unrelated,
# equally matching implicit ABC, refuse the temptation to guess.
if (t in registry and t not in cls.__mro__
and match not in cls.__mro__
and not issubclass(match, t)):
raise RuntimeError("Ambiguous dispatch: {} or {}".format(
match, t))
break
if t in registry:
match = t
return registry.get(match)
```
`_compose_mro(cls, registry.keys())` 使用了基于 C3 算法的变种,将抽象基类也插入进 mro 中了

上面的 P 的 `_compose_mro` 结果是
```
[<class '__main__.P'>, <class 'collections.abc.Iterable'>, <class 'collections.abc.Container'>, <class 'object'>]
```
那么问题来了,为什么要对抽象基类进行特别的约束呢?这里为什么不直接将 `Iterable` 作为最佳的匹配类型呢?
另外上例如果让 P 去多继承 `Iterable` 和 `Container` 则没有问题
已邀请:

要回复问题请先登录注册