簡體   English   中英

定義抽象方法,但需要子類實現

[英]Define an abstract method but require a subclass implementation

請注意,我認為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()

像這樣測試?

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

這也很有趣

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/

雖然我沒有用過。

您可以通過在父級中引發異常來強制執行此操作:

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如果已初始化)來使方法“抽象”。

請注意,我認為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()

我習慣稱此為“空白填充模式”(注意:這不是設計模式)。 您可以在抽象類中定義一個具體方法,該類調用抽象方法並用作帶有“空白”的模板(抽象方法)。 子類“填充空白”,實現抽象方法。 在您的簡單情況下:

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM