Python 3.x 相互Python子类(issubclass双向返回True)

Python 3.x 相互Python子类(issubclass双向返回True),python-3.x,class,inheritance,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):

所以我的理解是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)

有人能解释一下发生了什么吗?

os.PathLike
实现了数据模型:

这意味着任何实现
\uu fspath\uu
的类都将被视为子类

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

请用粘贴的实际代码编辑您的帖子,并包括您的类定义。我已经用@Brunodesshuilliers的实际代码更新了帖子。知道发生了什么吗?哇,多谢了,我以前从没听说过子类hook。有没有办法绕过这个漏洞,仍然使用isinstance()检查文件的不完整性(但不是目录不完整性)。例如,将File的实例(或File子类的实例)视为File,而不是Dir的实例。很多时候,这些看起来就像Python中不必要的复杂化。
>>> class Other: 
...     __fspath__ = None 
... 
>>> issubclass(Other, Path)
True