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.
号
实际上,
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 |
如果我打电话给
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 |
号
这将使方法"抽象化",方法是尝试在初始化时引发