【问题标题】:Python, calling subclass method from abstract basePython,从抽象基础调用子类方法
【发布时间】:2018-07-16 15:15:58
【问题描述】:

我正在尝试创建一个基本抽象类和子类来抽象出对后端数据库的访问。一个子类是 SQLAlchemy,另一个是 MongoDB 或其他 nosql。下面是一个非常简单的例子。在基类中,我需要为每种类型的对象创建一个 deleteObject,因为 noSQL 实现将需要这个,但是,任何使用 SQLAlchemy 的东西都只需要一个删除方法。我想通过为抽象库中的每种类型的对象使用以下方法来节省自己的打字时间。如果这可行,我就不必为 SQLAlchemy 子类中的每个对象类型定义 deleteObject,因为基本抽象只会将它传递给私有 __delete 函数。不幸的是,当我调用 deleteUser 时,它确实转到了抽象基函数,但是对 self.__delete(user) 的调用转到了抽象函数,即使子类定义了这个函数。当子类定义该函数的实现时,有没有办法确保抽象实现中的函数调用转到子类?

@abc.abstractmethod
def deleteUser(self, user):
    """Delete an user from the backend database"""
    print('abstractmethod')
    self.__delete(user)

@abc.abstractmethod
def __delete(self, object):
    print('dont go here')

【问题讨论】:

  • 听起来像多态,它应该在 Python 中默认以这种方式工作
  • @duffymo 我看不出有什么误解。子代覆盖 __delete 方法,OP 期望 deleteUser 调用该覆盖的方法。对我来说似乎是正常的继承?!也许我没听懂这个问题,你是怎么理解才写下这个评论的?
  • 我读到它是说 OP 希望父级了解子级实现。也许我误解了。如果他希望 Python 以应有的方式行事,那么为什么要问这个问题?
  • @duffymo,我不知道你在读什么,但你说的“父母可以提供所有孩子继承但可以根据他们选择覆盖的默认行为”正是我正在做的。所有单独的 deleteObjectName 函数的默认行为只是调用子类的 delete(object) 实现。问题只是我在函数名称“__delete”而不是“_delete”下有两个下划线。也许以后尽量不要那么粗鲁。

标签: python python-3.x abstract-class


【解决方案1】:

只是不要用两个__ 来命名你的方法,就像在.__delete 中一样。这不适用于“私有”方法,无论您可能已经阅读了哪些误导性文档 - 这只会导致方法名称与声明它的类名称混淆。

因此,在子类上调用self.__delete 将尝试在该子类上找到.__delete,并且只在该子类上找到,并且永远不会在超类上调用相同的方法——反之亦然:如果你对抽象超类有这样的调用,子类方法永远不会被调用,因为在内部它们被重命名为包含类名作为前缀。

只需使用一个_,一切就会开始如您所愿。

【讨论】:

  • 您说得对,先生。那你很。 Python 不是我的母语,感谢您的帮助。
猜你喜欢
  • 2015-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多