2016-12-09 204 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): 
     .... 

目前,如果我要補充,讓我們說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 

的變化不會影響任何的子類,直到我重新輸入他們到控制檯。我該如何改變這一點?

+0

你需要給足夠的代碼,以顯示你真正做([MVCE(https://stackoverflow.com/help/MCVE))。編輯超級_class_添加新方法應該可行(在定義子類之後這樣做效率不高,但不是不合理),但是我懷疑你錯誤地編輯了_instances,或者根本不編輯類。 – ShadowRanger

+0

我覺得我正在重新定義'ship',而讓其餘的類繼承自'ship'的前一個定義。我怎樣才能將函數添加到'ship'而不用重新輸入整個塊? – David

+0

對於重新定義整個類而不改變繼承的子類是正確的。我的答案涵蓋了這裏的細節;有一種方法適用於非抽象方法,但抽象方法不能使用這種技術。 – ShadowRanger

回答

1

如果你真的重新從頭開始的一類,它是一個不同的類;該子類仍然繼承舊版本ship。您不能僅僅定義一個名爲ship的新類,並希望子類能夠神奇地找到它。

通常情況下,如果你想猴補丁ship創建後添加新的方法,你可能只是這樣做:

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

但不幸的是,abstractmethod S表示ABC小號are an explicit exception to this rule

不支持在一個類中動態添加抽象方法,或者嘗試修改方法或類的抽象狀態。

您必須完全預先定義抽象基類,或者稍後重新定義整個類層次結構,以便將新的抽象方法添加到基類中。

+0

我可以將常規方法添加到基本抽象類而不會遇到此問題嗎? – David

+0

@大衛:這不應該導致問題。神奇的是與'ABCMeta'元類和'abstractmethod'描述符魔法的結合;元類鉤子在你結束類定義塊(因此需要用類定義所有抽象方法)時被調用,'ABCMeta'特別關注'abstractmethod',而不是常規方法。只要您不嘗試替換現有的抽象方法或添加新的方法,它應該可以正常工作;新的具體方法不能改變抽象繼承的規則。 – ShadowRanger