2013-10-02 53 views
0

我有一個關於初始化類的最佳實踐的問題。考慮一個複雜的類,並且有很多成員。在__init__()之外初始化它們是一種不好的做法,但是如何在沒有龐大方法的情況下處理該問題。初始成員的最佳實踐

一個例子:

class A: 
    def __init__(self): 
     self.member0 = "a" 

     # to prevent that the init method gets too big 
     # put some initialisation outside 
     init_other_stuff() 

    def init_other_stuff(self): 
     self.member1 = "b" 
     self.member2 = "c" 
     ... 

預先感謝。

[更新]澄清。目標不是把這些東西放到另一個長期的方法當然。相反,你可以初始化分成像不同的部分:

def init_network_stuff(self): 
    """ init network setup """ 
    self.my_new_socket = socket.socket(..) 


def init_local_stuff(self): 
    """ init local setup """ 
    self.my_new_logpath = "/foo/bar/log" 

... 
+5

很難給出明確的答案。在我看來,簡單地切斷'__init __()'並將其餘的函數移動到另一個函數只是爲了防止它變得「太長」是沒有意義的。另外,我認爲一個有很多成員的班級本身就是一個設計問題的標誌。 –

+6

*考慮一個複雜並且有很多成員的課程。*那是你的問題。這個班不應該有這麼多的屬性。也許你應該考慮重新設計你的班級系統。 – Oin

+0

所以爲了避免有一個長的__init__,你把它的內容移動到另一個長方法(任何人都可以調用,而沒有真正意識到它是一個init方法?) – njzk2

回答

0

我也會同意,有太多的屬性可能是抽象不足的跡象,這通常是很難發展&調試,所以改變你的設計可能是一個好主意。

但是,你確實有一個黃金徽章,所以你顯然已經在和(可能)知道你在做什麼,並可能有這樣做的理由。在這種情況下,我認爲按照您的建議分類初始化是個好主意。我會的唯一建議是使用_上分初始化函數來通知用戶,他們不打算正常使用即

class A: 
def __init__(self): 
    self.member0 = "a" 

    self.__init_other_stuff() 

def __init_other_stuff(self): 
    self.member1 = "b" 
    self.member2 = "c" 

等,這也隱藏了他們的製表完成大部分遊戲機&編輯。

你的其他選擇就是讓這個類實現該接口的一部分多個類的子類,如果你真的需要一個直接包含這些項目,即做這樣的事情:

class Logger(object): 
    def __init__(self): 
     self.logparam = 1 

class NetworkSource(object): 
    def __init__(self): 
     self.netparam = 2 

class A(Logger, NetworkSource): 
    def __init__(self): 
     Logger.__init__(self) 
     NetworkSource.__init__(self) 

In [2]: a = A() 

In [3]: a.<tab> 
a.logparam a.netparam 

然後,它會獲得這兩個類的功能,同時具有相對較短的init。恕我直言,多重繼承在概念上更復雜一點。