Подтвердить что ты не робот

Исключение для уведомления о том, что подкласс должен реализовывать метод в python

Предположим, я хочу создать абстрактный класс в python с некоторыми методами, которые будут реализованы подклассами. (в Python)

например:

class Base():
    def f(self):
        print "Hello."
        self.g()
        print "Bye!" 

class A(Base):
    def g(self):
        print "I am A"

class B(Base):
    def g(self):
        print "I am B"

Мне бы хотелось, чтобы если базовый класс был создан и вызван его метод f(), когда вызывается g(), исключение для повышения, сообщая, что подкласс должен реализовывать метод g().

Какая обычная вещь здесь? Должен ли я поднимать NotImplementedError? или есть более конкретный способ сделать это?

Большое спасибо!
Manuel

4b9b3361

Ответ 1

В Python 2.6 и выше вы можете использовать abc, чтобы сделать Base "фактически" абстрактным базовым классом:

import abc

class Base:
    __metaclass__ = abc.ABCMeta
    @abc.abstractmethod
    def g(self):
        pass
    def f(self): # &c

это гарантирует, что Base не может быть создан, и ни один из подклассов, которые не могут переопределить g, при выполнении задачи @Aaron, позволяя подклассам использовать super в своих реализациях g. В целом, гораздо лучшее решение, чем то, что мы использовали в Python 2.5 и ранее!

Боковое примечание: наличие базового наследования с объекта будет избыточным, потому что метаклас нужно явно указывать в любом случае.

Ответ 2

Сделайте метод, который ничего не делает, но все еще имеет docstring, объясняющий интерфейс. Получение NameError запутанно, и повышение NotImplementedError (или любое другое исключение, если на то пошло) нарушит правильное использование super.

Ответ 3

Питер Норвиг дал решение для этого в своем Python Часто задаваемые вопросы". Я воспроизведу его здесь. Проверьте IAQ, это очень полезно.

## Python
class MyAbstractClass:
    def method1(self): abstract

class MyClass(MyAbstractClass): 
    pass

def abstract():
    import inspect
    caller = inspect.getouterframes(inspect.currentframe())[1][3]
    raise NotImplementedError(caller + ' must be implemented in subclass')