Как использовать @abstractmethod для создания абстрактного интерфейса, который задает структуру аргументов его конструктора?

#python #oop #inheritance #interface #abstract-class

#python #ооп #наследование #интерфейс #абстрактный класс

Вопрос:

Я понимаю, почему приведенный ниже код вызывает исключение и, и некоторые способы избежать этого исключения, но я не понимаю предполагаемого способа использования @abstractmethod для создания абстрактного интерфейса.

Моя цель —

  • создайте абстрактный интерфейс Foo, который имеет конструктор с одним аргументом
  • и класс адаптера FooAdapter, который может быть подклассом классов, намеревающихся реализовать Foo.

Проблема в том, что если я добавлю соответствующие вызовы «super» в конструкторе, я в конечном итоге вызову abstractmethod и создам исключение.

  • Исправление # 1. Не добавляйте super . работает, но кажется неправильным, поскольку он может отбрасывать информацию, необходимую другим классам, если смешивать ее с другими классами
  • Исправление № 2. Не добавляйте подпись для инициализации в интерфейс. работает, но кажется неправильным, поскольку весь смысл интерфейса заключается в ОПРЕДЕЛЕНИИ ИНТЕРФЕЙСА. и я бы не стал этого делать, по крайней мере, для конструктора.

Я чувствую, что думаю об этом неправильно. Что за питонический способ??

 
from abc import ABC, abstractmethod

class Foo(ABC):
    @abstractmethod
    def __init__(self, my_arg):
        raise NotImplementedError


class FooAdapter(Foo):
    def __init__(self, my_arg):
        super().__init__()

 

ИЗ ПРИНЯТОГО ОТВЕТА НИЖЕ

Вам вообще не нужно использовать NotImplementedError, вместо этого просто используйте ‘pass’ . Механизм @abstractmethod выдаст исключение, если подкласс не реализует указанный метод.

Ответ №1:

Из abc.abstarctmethod описания:

Примечание: В отличие Java от абстрактных методов, эти абстрактные методы могут иметь реализацию. Эта реализация может быть вызвана с помощью super() механизма из класса, который ее переопределяет. Это может быть полезно в качестве конечной точки для суперзвонка в среде, использующей совместное множественное наследование.

Поэтому вам нужно просто поставить заглушку, ничего не делая, вместо того, чтобы поднимать NotImlementedError .

Комментарии:

1. О! Понял, так что ответ в моем случае заключается в том, чтобы ВООБЩЕ НЕ использовать «NotImplementedError». и используйте механизм @abstractmethod, чтобы убедиться, что все подклассы добавляют сюда какой-то метод. Понял. Спасибо! мое замешательство возникло из-за мысли, что я должен использовать NotImplementedError для обнаружения невыполнения, но в данном случае это неправильно.