相互的Python子类(issubclass双向返回True)

时间:2019-01-17 10:02:08

标签: python-3.x class inheritance

所以我的理解是Python不允许相互子类化(A是B的子类,而B也是A的子类),这是明智的,因为该概念没有太大意义。

那是说,我似乎有确切的情况,我不知道为什么会这样。

您可以使用以下简单方法重现该问题:

import os
from abc import ABC

class Path(os.PathLike, ABC):
    pass

class File(Path):
    def __fspath__(self):
        pass

class Dir(Path):
    def __fspath__(self):
        pass


issubclass(File, Dir)
issubclass(Dir, File)

isinstance(File(), Dir)
isinstance(Dir(), File)

对issubclass()的调用均返回True。调用isinstance()也是一样。

我从Path类继承了File和Dir类,并且从os.PathLike抽象基类继承了Path类。 File和Dir都应该是Path的子类,而不是彼此的子类。

我进一步尝试查看方法解析顺序,以查看类层次结构中的某些内容是否被破坏,但看起来很正常:

import inspect

inspect.getmro(File)
inspect.getmro(Dir)

输出:

(__main__.File, __main__.Path, os.PathLike, abc.ABC, object)
(__main__.Dir, __main__.Path, os.PathLike, abc.ABC, object)

有人可以解释发生了什么事吗?

1 个答案:

答案 0 :(得分:1)

os.PathLike实现数据模型__subclasshook__

class PathLike(abc.ABC):

    """Abstract base class for implementing the file system path protocol."""

    @abc.abstractmethod
    def __fspath__(self):
        """Return the file system path representation of the object."""
        raise NotImplementedError

    @classmethod
    def __subclasshook__(cls, subclass):
        return hasattr(subclass, '__fspath__')

这意味着实现__fspath__任何类将被视为子类。

>>> class Other: 
...     __fspath__ = None 
... 
>>> issubclass(Other, Path)
True