定义抽象方法但需要子类实现

时间:2015-06-05 01:43:01

标签: python

  

注意我不认为abc固有地解决了我正在寻找的问题。重申另一种,也许更好的方式,我正在寻找部分实现Parent.method的方法,但要求还有一个Subclass.method,它使用并添加到部分Parent.method实现。

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

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()

5 个答案:

答案 0 :(得分:1)

这样测试?

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()

答案 1 :(得分:1)

这也很有趣

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/

虽然我没有用过它。

答案 2 :(得分:0)

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

class base(object):
    def a_method(self):
        raise NotImplementedError("Implement this!")

class second(base):
    pass

如果我拨打second().a_method(),我会收到异常。在Python中没有抽象这样的东西,但这可能是你做到这一点的最佳方式。否则,

import abc
class base(object):
    __metaclass__ = abc.ABCMeta

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

如果初始化了TypeError,这将使方法“抽象”。

答案 3 :(得分:0)

  

请注意,我认为abc并不能解决我要找的问题。

实际上abc正是您想要的。在中定义实现 基类,但将其装饰为抽象需要派生类来重新定义它。 当然,这样做的副作用是阻止您实例化基类, 我认为在您的用例中可以。

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()

答案 4 :(得分:0)

我习惯称这种“空白填充模式”(注意:这不是设计模式)。您可以在抽象类中定义一个具体方法,该类调用抽象方法并用作带有“空白”的模板(抽象方法)。子类“填充空白”,实现抽象方法。在您的简单情况下:

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')

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