将类的私有变量定义为abstract

时间:2016-11-20 17:09:30

标签: python python-2.7 abstract-class abc

我想知道将类的私有变量设置为抽象的正确方法是什么。让我总结一下我的变量的属性:

  • 类变量
  • 私有
  • 抽象

我的课程结构如下:

from abc import ABCMeta

class AbstractClass(ABCMeta):
    __private_abstract_property = None   # Needs this as private abstract class variable
    # ... some functions


class ParentClass(AbstractClass):   # inherits `AbstractClass`
    # .. some more functions


class ChildClass1(ParentClass):    # inherits `ParentClass`
    __private_abstract_property = 'value1'   # value to be initialized here


class ChildClass2(ParentClass):    # inherits `ParentClass`
    __private_abstract_property = 'value2'

实现这一目标的正确方法是什么?

一种方法是使用abc.abstractproperty装饰器:

class AbstractClass(ABCMeta):
    @abstractproperty
    def __private_abstract_property(self):
        ...

或者,如Abstract Attributes in Python的答案所述:

class AbstractClass(ABCMeta):
    __private_abstract_property = NotImplemented

我想知道实现这一目标的正确方法(除了我提到的方法之外,任何方法都受到欢迎)。

编辑:以下是我要做的事情的一些描述:

  • 我有一个经理AbstractClass,它有一些与数据库相关的设置操作。它应该是抽象的,因为我不想要这个类的任何直接对象。它还有一些没有定义的功能

  • ParentClass源自AbstractClass。它将具有一些与从数据库中获取特定项相关的功能。同样,这个类也不知道它正在处理的数据库。

  • ChildClass实际上将拥有与之交互的数据库引擎。由于可以有不同的引擎保存相同类型的信息,我将在此处设置连接名称,并根据此连接作为源,ParentClass的函数将从数据库中获取信息。此外,除了ChildClass

  • 之外,ParentClass还可以提供其他功能

1 个答案:

答案 0 :(得分:3)

Python中有无隐私模型。在Java或C#名称是私有的意义上,双下划线名称不是私有的;这些名称是 class private

类私有意味着它们受到保护(通过在名称前添加类名称)来防止在子类中意外覆盖。这意味着在抽象类中放置双下划线名称时,绝对没有意义;子类不应该使用完全相同的名称。

请参阅参考文档的Reserved classes of identifiers section部分:

  

__*
  类私有名称。当在类定义的上下文中使用时,此类别中的名称将被重写以使用损坏的表单来帮助避免基类和派生类的“私有”属性之间的名称冲突。

无论如何,你不应该将任何私有放在抽象基类中。 ABCs类似于接口,记录 public API子类应提供的内容。

所以,即使你给了一个前导下划线的名称(仅按照惯例,信令,一个名称是内部实现的一部分,不能依赖于其他实现中保持可用)或者未来的版本),这些不应该是ABC的一部分;它不是抽象基类的范围来决定子类如何实现被禁止的方法和属性。