【问题标题】:Define private variable of class as abstract将类的私有变量定义为抽象
【发布时间】:2016-11-20 17:09:30
【问题描述】:

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

  • 类变量
  • 私人
  • 摘要

我的课程结构如下:

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 之外的其他功能

【问题讨论】:

  • 这听起来像是一个 XY Problem 尝试用 Python 编写 Java 的结果。你想完成什么任务?
  • @TigerhawkT3 对问题进行了编辑

标签: python python-2.7 abstract-class abc


【解决方案1】:

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

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

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

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

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

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

【讨论】:

  • 好的,假设我可以使用公共变量(按照惯例),那么我应该使用@abstractproperty 属性装饰器?
  • @MoinuddinQuadri:是的,那么您可以用@abstractproperty 记录您想要的属性。请注意,没有强制执行事情的实现方式,只有名称存在,@abstractmethod@abstractproperty
  • 但在这种情况下它将是实例变量,但我希望它是类变量。我最后对问题进行了编辑。也许它会帮助你理解我想要做什么
  • @MoinuddinQuadri:不,抽象类没有说明实例与类变量,只是名称需要存在。
  • @MoinuddinQuadri:您的ParentClassChildClass 类是实现。如果ParentClass 需要在类上设置某个名称,那么这是一个实现细节。这不是 ABC 的公共界面的一部分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-01
  • 2011-02-22
相关资源
最近更新 更多