2016-12-09 18 views
0

抽象クラス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): 
     .... 

現在、さんはship

def do_more_stuff(self):をしましょうを持っています
class ship(ABC): 
    def __init__(self): 
     ... 

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

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

コンソールに再入力するまで、変更はサブクラスに影響しません。これをどのように変更しますか?

+0

実際に行ったことを示すための十分なコードを提供する必要があります([MVCE](https://stackoverflow.com/help/MCVE))。新しいメソッドを追加するためにsuper _class_を編集する必要があります(サブクラスが定義された後ではあまり効率的ではありませんが、不合理ではありません)。間違いなく_instances_を編集しているか、クラスを編集していないと思われます。 – ShadowRanger

+0

私は 'ship'を定義し直していて、残りのクラスは' ship'の前の定義を継承しているように感じます。ブロック全体に再入力せずに関数を 'ship'に追加するにはどうすればいいですか? – David

+0

サブクラスの継承元を変更しないで、クラス全体を再定義するのは正しいことです。私の答えはここの詳細をカバーしています。非抽象メソッドでは機能する方法がありますが、抽象メソッドではこのテクニックを使用できません。 – ShadowRanger

答えて

1

実際にクラスをゼロから再定義すると、それは別のクラスです。サブクラスはまだshipの古いバージョンを継承しています。 shipという名前の新しいクラスを定義し、サブクラスがそれを魔法のように見つけることは期待できません。

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

しかし残念ながら、ABCare an explicit exception to this ruleためabstractmethod S:

新しいメソッドを追加するために作成した後、サル、パッチ shipしたい場合

通常は、あなただけのような何かを行うことができます

抽象メソッドをクラスに動的に追加したり、メソッドまたはクラスの作成後に抽象状態を変更しようとすると、サポートされません。

新しい抽象メソッドを基本クラスに追加する場合は、抽象基本クラスを完全に前に定義するか、後でクラス階層全体を再定義する必要があります。

+0

この問題が発生することなく、基本抽象クラスに通常のメソッドを追加できますか? – David

+0

@David:それは問題を引き起こすべきではありません。この魔法は 'ABCMeta'メタクラスと' abstractmethod'記述子の魔法の組み合わせに関係しています。クラス定義ブロックを終了した時点でメタクラスフックが呼び出されます(したがって、クラスですべての抽象メソッドを定義する必要があります)。また、 'ABCMeta'は通常のメソッドではなく' abstractmethod'に特に関係します。既存の抽象メソッドを置き換えたり新しいメソッドを追加したりしない限り、うまくいくはずです。新しい具体的なメソッドは、抽象継承のルールを変更することはできません。 – ShadowRanger

関連する問題