2016-11-30 10 views
1

Скажем, у меня есть следующий абстрактный класс Foo:Что я должен поставить в тело абстрактного метода в Python

import abc 

class Foo(abc.ABC): 

    @abc.abstractmethod 
    def bar(self): 
     raise NotImplementedError 

Что я должен положить в теле метода bar?

Я вижу много кода, который имеет raise NotImplementedError, как показано выше. Однако это кажется излишним, поскольку любой подкласс, который не реализует bar, поднимет TypeError: Can't instantiate abstract class Foo with abstract methods bar при его создании.

Является ли это Pythonic оставить bar пустым, следующим образом:

import abc 

class Foo(abc.ABC): 

    @abc.abstractmethod 
    def bar(self): 
     ... 

Это то, что делается в документации Python для Abstract Base Classes, но я не уверен, что это просто заполнитель или фактический пример как писать код.

Если уместно оставить bar только с тремя точками (...), когда следует использовать NotImplementedError?

ответ

4

Документация направляет вас на пример. Вам не обязательно следовать этому.

Вы можете указать значение по умолчанию; подклассы по-прежнему могут использовать super() для вызова вашей реализации. Это то, что делают большинство классов collections.abc; см. source code.

Size, например, возвращает 0 для __len__:

class Sized(metaclass=ABCMeta): 
    # ... 
    @abstractmethod 
    def __len__(self): 
     return 0 
+0

Спасибо за ссылку. [MutableSet.add] (https://hg.python.org/cpython/file/3.5/Lib/_collections_abc.py#l508) и [MutableSet.discard] (https://hg.python.org/cpython/file /3.5/Lib/_collections_abc.py#l513) делают рейз 'NotImplementedError', поэтому я думаю, что я должен придерживаться этого соглашения вместо' ... '. – ostrokach