【问题标题】:Updating Classes that inherit from abstract classes更新从抽象类继承的类
【发布时间】:2017-04-24 10:24:56
【问题描述】:

我有一个抽象类ship

from abc import ABC, abstractmethod
class ship(ABC):
    def __init__(self):
         ...

    @abstractmethod
    def do_stuff(self,stuff,things):
         pass

我有多个继承自它的类(destroyercruiserpatrol_boat 等...)

class carrier(ship):
    def __init__(self):
         ....
    def do_stuff(self,stuff,things):
         ....

目前,如果我要添加,假设 def do_more_stuff(self):ship

class ship(ABC):
    def __init__(self):
         ...

    @abstractmethod
    def do_stuff(self,stuff,things):
         pass

    @abstractmethod
    def do_more_stuff(self,stuff,things):
        pass

在我将它们重新输入到控制台之前,这些更改不会影响任何子类。我该如何更改?

【问题讨论】:

  • 你需要提供足够的代码来展示你实际做了什么 (MVCE)。编辑超 class 以添加新方法应该可以工作(在定义子类之后这样做效率有点低,但并非不合理),但我怀疑你错误地编辑了 instances i>,或者根本不编辑课程。
  • 我觉得我在重新定义ship,同时让剩余的类继承ship的先前定义。如何在不重新输入整个块的情况下向ship 添加函数?
  • 重新定义整个类而不改变子类继承的内容是正确的。我的回答涵盖了这里的细节;有一种方法适用于非抽象方法,但抽象方法不能使用这种技术。

标签: python class inheritance abstract abc


【解决方案1】:

如果你真的从头开始重新定义一个类,它就是一个不同的类;子类仍然继承自旧版本的ship。您不能只定义一个名为 ship 的新类并期望子类能神奇地找到它。

通常,如果您想在创建后对 ship 进行猴子补丁以添加新方法,您可以执行以下操作:

def do_more_stuff(self,stuff,things):
    pass
ship.do_more_stuff = do_more_stuff

但不幸的是,abstractmethods 为 ABCs are an explicit exception to this rule

不支持向类动态添加抽象方法,或在方法或类创建后尝试修改其抽象状态。

如果您想向基类添加新的抽象方法,您必须先完全定义抽象基类,或者稍后重新定义整个类层次结构。

【讨论】:

  • 我可以在基本抽象类中添加常规方法而不会遇到这个问题吗?
  • @David:这应该不会造成问题。魔术与ABCMeta 元类和abstractmethod 描述符魔术的组合有关;在结束类定义块时调用元类挂钩(因此需要用类定义所有抽象方法),ABCMeta 特别关注abstractmethod,而不是常规方法。只要您不尝试替换现有的抽象方法或添加新的抽象方法,它就可以正常工作;新的具体方法不能改变抽象继承的规则。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-10
  • 1970-01-01
  • 1970-01-01
  • 2021-01-23
  • 2018-05-27
  • 1970-01-01
  • 2013-06-10
相关资源
最近更新 更多