Есть ли какой-то механизм, обеспечивающий реализацию вложенных интерфейсов в абстрактных классах в Python? - PullRequest
1 голос
/ 04 мая 2020

Я хочу создать класс, который имеет некоторый вложенный класс, который определяет некоторый контракт в Python. Примером использования является типизированный объект конфигурации. Моя попытка сделать это ниже:

from typing import Mapping
from abc import ABCMeta, abstractmethod

class BaseClass(metaclass=ABCMeta):
    # If you want to implement BaseClass, you must also implement BaseConfig
    class BaseConfig(metaclass=ABCMeta):
        @abstractmethod
        def to_dict(self) -> Mapping:
            """Converts the config to a dictionary"""

Но, к сожалению, я могу создать экземпляр подкласса BaseClass без реализации BaseConfig:

class Foo(BaseClass):
    pass

if __name__ == "__main__":
    foo = Foo()

Есть ли способ заставить подкласс должен также реализовать внутренний класс?

1 Ответ

0 голосов
/ 04 мая 2020

Не похоже, что это возможно в настоящее время. Наиболее близким является создание двух абстрактных классов (соответствующих внешним и внутренним классам) и принуждение разработчика предоставить конструктор cls для конкретного внутреннего класса; Например:

from abc import ABCMeta, abstractmethod

class Inner(metaclass=ABCMeta):
    @abstractmethod
    def __str__(self):
        pass

class Outer(metaclass=ABCMeta):
    inner_cls = Inner

    def shout(self, *args, **kwargs):
        inner = self.inner_cls(*args, **kwargs)
        print(f"My inner is {inner}!!!")

class FooInner(Inner):
    def __str__(self):
        return "FooInner"

class FooOuter(Outer):
    inner_cls = FooInner

Для этого требуется Inner, чтобы иметь хотя бы один abstractmethod, в противном случае его можно создать как реализацию inner_cls по умолчанию.

...