关于python:定义一个抽象方法,但需要一个子类实现

Define an abstract method but require a subclass implementation

Note I do not think that abc inherently solves what I'm looking for. Restating in another, maybe better way, I'm looking of a way to partially implement a Parent.method but require that there is a Subclass.method also, which uses and adds to the partial Parent.method implementation.

我想部分地定义一个抽象类方法,但仍然要求该方法也在子类中实现。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class AbstractClass(object):
    def amethod():
        # some code that should always be executed here
        vars = dosomething()

        # But, since we're the"abstract" class
        # force implementation through subclassing
        if <somehow determine whether this has not been subclassed>:
            raise NotImplementedError

class ActualClass(AbstractClass):
    def amethod():
        # Actual class code
        code_here()

        # And execute the super class code.
        super(ActualClass, self).amethod()


这也很有趣

1
2
3
4
5
def abstractmethod(method):
    def default_abstract_method(*args, **kwargs):
        raise NotImplementedError('call to abstract method ' + repr(method))    
    default_abstract_method.__name__ = method.__name__        
    return default_abstract_method

http://code.activestate.com/recipes/577666-abstract-method-decorator/

虽然我没用过。


像这样测试?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class AbstractClass(object):
    def amethod(self):
        # some code that should always be executed here
        print(" AbstractClass.amethod()")

        # But, since we're the"abstract" class
        # force implementation through subclassing
        if self.__class__ == AbstractClass:
            raise NotImplementedError

class ActualClass(AbstractClass):
    def amethod(self):
        # Actual class code
        print(" ActualClass.amethod()")

        # And execute the super class code.
        super(ActualClass, self).amethod()


#a = AbstractClass()
#a.amethod()

b = ActualClass()
b.amethod()


我用来调用这个"填充空白模式"(NB:这不是一个设计模式)。您在抽象类中定义了一个具体的方法,该方法调用抽象方法,并使用"blank"(抽象方法)作为模板工作。实现抽象方法的子类"填充空白"。简单来说:

1
2
3
4
5
6
7
8
9
10
11
12
13
class AbstractClass(object):
    def amethod(self):
        self._amethod()
        print('Common operations')

    @abc.abstractmethod
    def _amethod(self, vars):
        pass


class ConcreteClass(AbstractClass):
    def _amethod(self):
        print('Concrete class code')

通常,您可以给抽象方法起一个更好的名字。


Note I do not think that abc inherently solves what I'm looking for.

实际上,abc正是你想要的。在中定义实现但将其修饰为抽象的基类需要派生类来重新定义它。当然,这有一个副作用,即阻止您实例化基类,在您的用例中,我认为这是正常的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import abc


# inheritance from abc.ABC is important, as otherwise the decorators don't do anything
class AbstractClass(abc.ABC):
    @abc.abstractmethod
    def amethod(self):
        # some code that should always be executed here
        print("Base implementation")


class ActualClass(AbstractClass):
    # will return TypeError: Can't instantiate abstract class ActualClass with abstract methods amethod if not redefined
    def amethod(self):
        # Actual class code
        print("Actual implementation")

        # And execute the super class code. (only one super class so less confusing)
        super().amethod()


a = ActualClass()
a.amethod()

您可以通过在父级中引发异常来强制它:

1
2
3
4
5
6
class base(object):
    def a_method(self):
        raise NotImplementedError("Implement this!")

class second(base):
    pass

如果我打电话给second().a_method(),我会得到一个例外。在Python中没有抽象的东西,但这可能是最好的方法。否则,

1
2
3
4
5
6
7
8
import abc
class base(object):
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def something_to_implement(this):
       """A docstring"""
        return

这将使方法"抽象化",方法是尝试在初始化时引发TypeError