2009-07-07 67 views
1

我implementig在this way一個複合模式:Python的複合圖案的異常處理&pylint的

1)中的 「抽象」 組分是:

class Component(object): 
    """Basic Component Abstraction""" 
    def __init__(self, *args, **kw): 
     raise NotImplementedError("must be subclassed") 

    def status(self): 
     """Base Abstract method""" 
     raise NotImplementedError("must be implemented") 

2)葉:

class Leaf(Component): 
    """Basic atomic component 
    """ 
    def __init__(self, *args, **kw): 
     self.dict = {} 

    def status(self): 
     """Retrieves properties 
     """ 
     return self.dict 

的問題是,產生pylint的,當然,這樣的警告:

Leaf.__init__: __init__ method from base class 'Component' is not called 

但進入我的葉子,我不能要求:無例外的提高

def __init__(self, *args, **kw): 
    Component.__init__(self, *args, **kw) 
    self.dict = {} 

我必須忽略pylint警告還是存在一些錯誤的編碼?

回答

4

抽象初始化器是一個壞主意。您的代碼可能會發展,因此您想在根組件中進行一些初始化。即使你不明白爲什麼需要初始化器的實現。對於某些子類,空的初始化器將是一個可接受的選擇。

如果你不想讓身邊的Component類的任何實例,檢查,在初始化:

class Component(object): 
    def __init__(self, **kwargs): 
     assert type(self) != Component, "Component must not be instantiated directly" 

class Leaf(Component): 
    def __init__(self, some, args, **kwargs): 
     # regular initialization 
     Component.__init__(self, **kwargs) 
+0

你的建議:「抽象初始化器是一個壞主意,你的代碼可能演變讓你想要做的根組件一些初始化。」,但我到一個組合模式,它必須有這樣的抽象。 – DrFalk3n 2009-07-07 10:04:54

+3

@ DrFalk3n。讓我們不要迷戀該模式的Java版本。 Java人喜歡他們的抽象類。 Python根本沒有這個。我們都是大人,我們都知道抽象類是行不通的。拋出引發NotImplemented的抽象__init__確實沒問題。您不必在Python中重新提供Java/C++的愚蠢。 – 2009-07-07 10:13:42

+0

複合模式並不意味着你不能在基類中有共同的初始化代碼。你想避免的是基類的實例化。因此,檢查與如果類型(個體經營)==部件:引發異常(「組件不能直接實例化」) – 2009-07-07 10:15:35

1

你要保證,基類組件沒有實例化。這是一種在其他編程語言(如C++)中常見的高貴典雅(在這種編程語言中,構造函數可以是私有的,以防止直接使用)。

但它在Python中不受支持。 Python不支持所有編程概念,也更「動態」。因此,初始化以「Pythonic」方式完成,因此您的概念不受支持。

Python比其他語言更基於信任 - 所以,例如靜態變量不被支持,私有變量只能以有限的方式。

你可以做什麼(當你不信任你的模塊的用戶時) - 你可以通過命名它來隱藏基類「_Component」 - 使它成爲一個內部祕密。但這當然會造成其他麻煩。

1

編碼本身不錯,但組件的__init__根本就不需要。如果你需要它,你可以忽略pylint,但最好從Component中刪除__init__

擁抱動感!

2

另一個建議以補充馬庫斯的想法:

如果你真的要,我建議你使用__new __和檢查給定對象類型。當它是「分量」,你可以解僱你的例外:

class Component(object): 
"""Basic Component Abstraction""" 

def __new__(objType, *args, **kwargs): 
    if objType == Component: 
     raise NotImplementedError("must be subclassed") 
    return object.__new__(type, *args, **kwargs) 

當創建一個子類,OBJTYPE會=組件和所有將被罰款!

2

重命名您的類組件應該對AbstractComponent有所幫助。如果它不應該被子類調用,則不要在基類中提供__init__方法。