2012-09-21 66 views
1

我想在這一點上用兩種方法創建一個類(我也希望能夠明顯地改變類)。類設計:共享很多相同代碼的方法

class ogrGeo(object): 

    def __init__(self): 
     pass 

    def CreateLine(self, o_file, xy): 
     #lots of code 


    def CreatePoint(self, o_file, xy): 
     # lot's of the same code as CreateLine(), 
     # only minor differences 

爲了保持清潔,並重復爲 更少的代碼儘可能我問了一些建議。兩種方法CreateLine()CreatePoint()共享很多代碼。減少冗餘: 應該定義這兩種方法都可以調用的第三種方法嗎? 在這種情況下,您仍可以分別撥打 o = ogrGeo() o.CreateLine(...) o.CreatePoint(...)。 或者我應該將它們合併成一種方法?還有沒有想過或不知道的另一個解決方案?

感謝您的任何建議。

+0

感謝所有的建議傢伙。最後,我將它作爲一個具有兩個公共方法和兩個輔助函數的類來實現,以儘可能多地模塊化代碼。我對結果非常滿意,特別是因爲它的代碼會使我的類的擴展非常簡單(例如'create_polygon',...方法)。 – LarsVegas

回答

2

這是完全正常的分解出共同的代碼放到一個(私人)輔助方法:

class ogrGeo(object) 
    def __init__(self): 
     pass 

    def CreateLine(self, o_file, xy): 
     #lots of code 
     value = self._utility_method(xy) 

    def CreatePoint(self, o_file, xy): 
     # lot's of the same code as CreateLine(), 
     # only minor differences 
     value = self._utility_method(xy) 

    def _utility_method(self, xy): 
     # Common code here 
     return value 

的方法可以返回一個值,或者它可以直接操縱上self的屬性。

建議的意見:閱讀Python style guide並堅持它的約定。大多數其他的python項目都可以,如果你願意的話,它會讓你的代碼更容易理解其他Python開發者。

+2

你提到我的方法名我想......真的。我的壞習慣。 – LarsVegas

3

您是否應該將方法合併爲一個是API設計的問題。如果這些功能有不同的目的,那麼你就把它們分開。我合併他們,如果客戶端代碼很可能遵循的模式

if some_condition: 
    o.CreateLine(f, xy) 
else: 
    o.CreatePoint(f, xy) 

但除此之外,不合並。相反,將公共代碼重構爲私有方法,或者如果通用代碼不觸及self,則甚至可以使用獨立函數。 Python沒有內置在該語言中的「私有方法」的概念,但具有前導_的名稱將被識別爲這樣。

+0

如果我決定使用獨立功能,繼承如何?難道你不應該永遠保持代碼,以免你的課程導致? – LarsVegas

+0

@larsvegas:爲什麼?這意味着你永遠不能在課堂外打電話。我傾向於將效用函數放在模塊中而不是類中,但如果你不喜歡這樣,你可以使用'staticmethod'。 Python不是Java :) –

+0

不,這不是我的意思。但如果你基於'ogrGeo'派生一個類,如果它是獨立的,你將不會繼承這個效用函數,對嗎? – LarsVegas

1

對於那些會重疊的代碼段,考慮這些代碼是否也可以是它們自己的獨立函數。然後CreateLine將由幾個調用某些函數組成,其中參數選擇對於CreateLine有意義,同時CreatePoint將是具有用於創建點的適當參數的幾個函數調用。

即使這些新的輔助功能不會在其他地方使用,最好將它們模塊化爲單獨的功能,而不是複製/粘貼代碼。但是,如果創建這些結構所需的輔助功能非常具體,那麼爲什麼不把它們分解到自己的類中?

您可以創建一個「對象」類,它涉及創建對象的所有基礎知識,然後包含派生自「對象」的「線」和「點」類。在這些類中,重寫必要的函數以便構造是特定的,依賴於基礎「對象」類中用於重疊代碼部分的輔助函數。

然後ogrGeo類將構造這些其他類的實例。即使「線」或「形狀」的最終消費者不需要完整的類對象,仍然可以使用此設計,並賦予ogrGeo返回線實例或Point實例的子部分的能力消費者確實希望使用。

1

這幾乎沒有關係。您希望類方法對於調用程序儘可能地可用,並且使用兩種方法比使用附加參數創建對象類型的方法稍微簡單和高效:

def CreateObj(self, obj, o_file, xy) # obj = 0 for Point, 1 for Line, ... 

建議:使用單獨的API調用,並將常用代碼納入可在類中調用的方法中。

0

你也可以去另一個方向。特別是,如果以下的話:

def methA/B(...): 
    lots of common code 
    small difference 
    lots of common code 

那麼你可以做

def _common(..., callback): 
    lots of common code 
    callback() 
    lots of common code 
def methA(...): 
    def _mypart(): do what A does 
    _common(..., _mypart) 
def methB(...): 
    def _mypart(): do what B does 
    _common(..., _mypart) 
相關問題