исключение для уведомления о том, что подкласс должен реализовать метод в Python - PullRequest
10 голосов
/ 13 августа 2010

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

Ответы [ 3 ]

13 голосов
/ 13 августа 2010

В 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 и более ранних версиях!

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

3 голосов
/ 13 августа 2010

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

0 голосов
/ 13 августа 2010

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