2010-03-24 106 views
14

好的我有兩個真正大的類,每個> 1k行,每個我現在分成多個類。然後他們使用多重繼承進行重組。現在我想知道,如果有更清潔/更好的pythonic這樣做的方式。完全分解它們會導致無數次的調用,我認爲這不應該是它應該完成的方式。Python類設計 - 將大類拆分爲多個類來組合功能

爲了讓事情在這裏明確就是它現在的樣子:

from gui_events import GUIEvents # event handlers 
from gui_helpers import GUIHelpers # helper methods that don't directly modify the GUI 

# GUI.py 
class GUI(gtk.Window, GUIEvents, GUIHelpers): 
    # general stuff here stuff here 

的一個問題是,這是pylint的抱怨給我的萬億結果「INIT不叫」 /「未定義的屬性」 /「屬性訪問在定義之前「警告。

編輯:
你可能想看看代碼,讓自己一個什麼整件事其實是圖片。
http://github.com/BonsaiDen/Atarashii/tree/next/atarashii/usr/share/pyshared/atarashii/

請注意,我真的想什麼讓這件事儘可能乾燥,我使用pylint的檢測代碼重複,它抱怨是進口的唯一的事。

+0

東西不加起來。問題是「>每行1k」。存儲庫中的實際代碼是356行。請修復問題或鏈接。 – 2010-03-24 10:39:35

+0

你需要總結一下:http://github.com/BonsaiDen/Atarashii/blob/next/atarashii/usr/share/pyshared/atarashii/gui.py http://github.com/BonsaiDen/Atarashii/blob/ next/atarashii/usr/share/pyshared/atarashii/gui_events.py和http://github.com/BonsaiDen/Atarashii/blob/next/atarashii/usr/share/pyshared/atarashii/gui_helpers.py,因爲我已經將東西(目前只有968線,因爲我最近把一些東西移到其他文件)。同時檢查一起有1,1k行的視圖*文件。 – 2010-03-24 11:54:15

回答

6

如果您想使用多重繼承將所有內容組合到一個大類中(這樣做可能有意義),那麼您可以重構每個父類,以便每個方法和屬性都是私有的(以' __')或具有該類別特有的短2-3字符前綴。例如,GUIEvents類中的所有方法和屬性都可以從ge_開始,GUIHelpers中的所有內容都可以從gh_開始。通過這樣做,您可以實現使用單獨子類實例的一些明確性(self.ge.doSomething() vs self.ge_doSomething()),並且可以避免衝突的成員名稱,這是將這樣的大類合併爲一個主要風險時的主要風險。

+0

我想這就是我去這裏的方式,因爲1.使用搜索/替換很容易,2.它會減少衝突的可能性,我也可以使用更通用的名稱,比如um_get_items,而不是(update_messages).get_messages和3.正如你已經說過的那樣,它會使代碼變得清晰並顯示方法的起源。總而言之,這很簡單,也許我花了5周的時間編程這個東西后想到一些複雜的:D – 2010-03-24 06:21:43

1

我認爲這是一個比Python問題更普遍的面向對象設計問題。 Python幾乎爲您提供了所有經典的OOP工具,方便打包。 (?比如怎樣做GUIEventsGUIHelpers類包含)你不得不更詳細地說明這個問題

一個Python特定的方面來考慮是:Python支持多種編程範式,並且往往是最好的解決辦法是不是面向對象。這裏可能是就是這種情況。但是,再次,你必須投入更多的細節才能獲得有意義的答案。

+0

你可以看看這裏的課程:http://github.com/BonsaiDen/Atarashii/tree/next/atarashii/usr/share/pyshared/atarashii/ GUIEvents主要是關於如何處理用戶點擊按鈕。 GUIHelpers設置了一些像標籤和其他小東西,還提供了一些實用功能,如is_ready。我還沒有完全決定哪些方法屬於每個「子類」。 – 2010-03-24 04:14:15

0

通過實施模型 - 視圖 - 控制器設計,您的代碼可能會大大改善。根據你的GUI和工具的設置,你可能也會受益於GUI的「widgetizing」部分,所以你不必擁有一個巨大的模型 - 視圖 - 控制器,而是擁有一個主要的模型 - 視圖 - 控制器來管理一堆較小的模型視圖控制器,每個控制器都用於GUI的不同部分。這將允許您將工具和GUI分解爲許多類,並且您可能能夠重用其中的部分內容,從而減少需要維護的代碼總量。

雖然python支持多種編程範例,但對於GUI工具來說,最好的解決方案几乎總是一個面向對象的設計。

+0

問題是我目前還沒有看到進一步減少整個事情的方法,Dialogs/TrayIcon和HTMLViews已經在他們自己的類中,所以這個大的GUI事物目前只是管理這些之間的綁定並設置像狀態欄。此外,我已經把代碼幹掉了......我能夠成像的唯一東西就是把GUI分解成一個組件,它實際上修改了可見的東西,另一個組件只是處理事件等,但那會導致self.otherself。 foo調用:/ – 2010-03-24 06:00:58

5

首先找到您的應用程序需要使用的模型現實世界概念的類。這些都是課堂的自然人選。

嘗試儘量避免多重繼承;它很少有用,而且總是有點混亂。相反,請使用功能組合(「HAS-A」關係)爲您的由其他對象構成的對象提供豐富的屬性。

記得讓每個方法都做一個小的,具體的東西;這必然意味着要將太多事情分解成小塊的方法。

重構您發現許多此類方法正在重複彼此的功能的情況;這是另一種找到應該屬於不同類別的自然功能集合的另一種方法。

+1

+1:「2個真正的大類> 1k行」ouch。這顯然忽略了OO設計的重點。一個類中的所有事件處理程序顯然是錯誤的。活動助手不是班級設計。 – 2010-03-24 10:34:25

0

一種可能性是類屬性分配進口功能:

在文件a_part_1.py

def add(self, n): 
    self.n += n 
def __init__(self, n): 
    self.n = n 

而且在主類文件:

import a_part_1 

class A: 
    __init__ = a_part_1.__init__ 
    add = a_part_1.add 

或者,如果你不想在添加新方法時更新主文件:

class A: pass 

import a_part_1 
for k, v in a_part_1.__dict__.items(): 
    if callable(v): 
     setattr(A,k,v)