Взаимные подклассы Python (issubclass возвращает True в обоих направлениях) - PullRequest
0 голосов
/ 17 января 2019

Таким образом, я понимаю, что 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 ().

Я вложил в подклассы классы File и Dir из класса Path и подклассифицировал класс Path из абстрактного базового класса os.PathLike. 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 голосов
/ 22 января 2019

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...