在Python中实现抽象属性

时间:2016-02-04 17:24:33

标签: python oop python-3.x

在Python中处理抽象属性的最佳,最Pythonic方法是什么?如果我想实现一个具有抽象属性和具体方法的基类,我可以这样做类似于以下内容。

class BaseClass(object):
    __metaclass__ = ABCMeta

    @abstractmethod
    def property1(self):
        pass

    @abstractmethod
    def property2(self):
        pass

    @abstractmethod
    def property3(self):
        pass

    @abstractmethod
    def abstract_method(self):
        pass

    def concrete_method(self):
        return self.property1 + self.property2

但是,当我去实现继承类时,我需要将每个属性实现为私有属性的getter方法。

class Klass(BaseClass):
    def __init__(property1, property2, property3):
        self.__property1 = property1
        self.__property2 = property2
        self.__property3 = property3

    @property
    def property1(self):
        return self.__property1

    @property
    def property2(self):
        return self.__property2

    @property
    def property3(self):
        return self.__property3

这似乎都是不必要的冗长,并使代码比它需要的更加模糊。

如果继承课程没有实现自己的版本,我不会喜欢具体实施并提出NotImplementedError的想法。

有更好的方法吗?

1 个答案:

答案 0 :(得分:2)

您不需要将属性实现为属性。您只需要名称在类上存在即可。因此,以下使用常规属性将起作用:

class Klass(BaseClass):
    property1 = None
    property2 = None
    property3 = None

    def __init__(property1, property2, property3):
        self.property1 = property1
        self.property2 = property2
        self.property3 = property3

    def abstract_method(self):
        # implementation for the abstract method

请注意,有一个abstractproperty decorator更好的文档,您希望将这些名称用作简单值,而不是调用方法:

class BaseClass(object):
    __metaclass__ = ABCMeta

    @abstractproperty
    def property1(self):
        pass

    @abstractproperty
    def property2(self):
        pass

    @abstractproperty
    def property3(self):
        pass

    @abstractmethod    
    def abstract_method(self):
        pass

    def concrete_method(self):
        return self.property1 + self.property2