0

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

  • 类变量
  • 私人的
  • 抽象的

我的课程结构如下:

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):
        ...

或者,正如在 Python 中抽象属性的答案中提到的那样:

class AbstractClass(ABCMeta):
    __private_abstract_property = NotImplemented

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


编辑:这是我想要做的一些描述:

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

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

  • ChildClass实际上将拥有它应该与之交互的数据库引擎。由于可能有不同的引擎拥有相同的信息,我将在此处设置连接名称并基于此连接作为源,ParentClass函数将从数据库中获取信息。此外,ChildClass除了可以具有其他功能ParentClass

4

1 回答 1

3

Python中没有隐私模型。双下划线名称在 Java 或 C# 名称是私有的意义上不是私有的;这样的名字是类私有的。

私有类意味着它们受到保护(通过在其名称前加上类名)免受子类中的意外覆盖。这意味着将双下划线名称放在抽象类中绝对没有意义。子类不应使用完全相同的名称。

请参阅参考文档的标识符保留类部分:

__*
类私有名称。此类别中的名称,当在类定义的上下文中使用时,会被重新编写以使用重整形式,以帮助避免基类和派生类的“私有”属性之间的名称冲突。

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

因此,即使您为名称指定了一个前导下划线(仅按照惯例,表明名称是内部实现的一部分,并且不能依赖于在其他实现或未来版本中保持可用),这些也不应该是一部分ABC的;规定子类如何实现被禁止的方法和属性不是抽象基类的权限。

于 2016-11-20T17:13:06.647 回答