2011-11-14 75 views
1

我已經寫了一些代碼,允許術語'工作'普遍用於執行一項獨特的任務。可以通過設置初始變量「job_type」來選擇特定的作業。從最初的變量中選擇一個特定的子類來執行適當的工作。也許代碼會更有意義:)正確的類繼承

if __name__=='__main__': 
    # these variables would normally be called in from a config file 
    job_type = 'job1' 
    uni_var = 10 

    job_select = superClass(job_type, uni_var) 
    job_select.job()   


class superClass(object): 
    def __init__(self, job_type, uni_var): 
     self.job_type = job_type 
     self.uni_var = uni_var 

     if self.job_type == 'job1': 
      self.jobChoice = option1() 
     else: 
      self.jobChoice = option2() 

    # This is the definition called by the main function it then 
    # redirects the request to the appropriate job sub class 
    def job(self): 
     self.jobChoice.job() 

class option1(superClass): 
    def __init__(self): 
     pass 

    def job(self): 
     print 'job option 1' 
     print uni_var 

class option2(superClass): 
    def __init__(self): 
     pass 

    def job(self): 
     print 'job option 2' 
     print uni_var 

這段代碼背後的想法是允許單個/常量「主」功能,行動上的各種變量「工作類型」純粹基於獨特的任務。它似乎很好。

我的問題(作爲一個非常缺乏經驗的編碼員)是,我有沒有正確的方式或有更好的方式來做事情?

另外,我有沒有在superClass中正確設置變量'uni_var',以便在所有/任何superClass子類中正確共享?

謝謝。

回答

1

我懷疑你真正想要的是在這裏使用Factory Method Pattern

你可以更改您的代碼是這樣的:

if __name__=='__main__': 
    # these variables would normally be called in from a config file 
    job_type = 'job1' 
    uni_var = 10 

    job_select = superClass.optionFactory(job_type, uni_var) 
    job_select.job()   


class superClass(object): 
    def __init__(self, job_type, uni_var): 
     self.job_type = job_type 
     self.uni_var = uni_var 

    # This is the definition called by the main function it then 
    # redirects the request to the appropriate job sub class 
    def job(self): 
     raise NotImplementedError() 

    @staticmethod 
    def optionFactory(job_type, uni_var): 
     "Return an instance of superClass based on job_type and uni_var." 
     if job_type == "job1": 
      return option1(job_type, uni_var) 
     else: 
      return option2(job_type, uni_var) 

class option1(superClass): 
    def __init__(self, job_type, uni_var): 
     super(option1, self).__init__(job_type, uni_var) 

    def job(self): 
     print 'job option 1' 
     print uni_var 

class option2(superClass): 
    def __init__(self, job_type, uni_var): 
     super(option2, self).__init__(job_type, uni_var) 

    def job(self): 
     print 'job option 2' 
     print uni_var 

但是,請注意,此實現將需要superClass在每次創建一個新的子類時間而改變。另一種選擇是使optionFactory方法成爲獨立功能(而不是superClass的方法)。像這樣:

if __name__=='__main__': 
    # these variables would normally be called in from a config file 
    job_type = 'job1' 
    uni_var = 10 

    job_select = optionFactory(job_type, uni_var) 
    job_select.job()   


class superClass(object): 
    def __init__(self, job_type, uni_var): 
     self.job_type = job_type 
     self.uni_var = uni_var 

    # This is the definition called by the main function it then 
    # redirects the request to the appropriate job sub class 
    def job(self): 
     raise NotImplementedError() 

class option1(superClass): 
    def __init__(self, job_type, uni_var): 
     super(option1, self).__init__(job_type, uni_var) 

    def job(self): 
     print 'job option 1' 
     print uni_var 

class option2(superClass): 
    def __init__(self, job_type, uni_var): 
     super(option2, self).__init__(job_type, uni_var) 

    def job(self): 
     print 'job option 2' 
     print uni_var 

def optionFactory(job_type, uni_var): 
    "Return an instance of superClass based on job_type and uni_var." 
    if job_type == "job1": 
     return option1(job_type, uni_var) 
    else: 
     return option2(job_type, uni_var) 
+0

你可以使這更簡單;如果** all **你的'__init__'方法是用相同的參數調用'super(...).__ init__',那麼你可以完全跳過實現'__init__'並繼承它。 – Ben

+0

謝謝本。這幾乎是所有的事情發生,相同的爭論(雖然有不止兩個)將用於所有的子類。如何跳過實現__init__並繼承這些爭論? – user788462

+0

@ user788462只要不在子類中寫入__init__方法,它們就會自動使用超類'__init__'。 – Ben

1

不要使用類作爲工廠,它很愚蠢。您只需要跨實現的一致接口。

class JobA(object): 
    def do_job(self, arg): 
     print 'job a', arg 

class JobB(object): 
    def do_job(self, arg): 
     print 'job b', arg 

job_types = { 
    'job1': JobA, 'job2': JobB 
} 

job_type = 'job1' 
uni_var = 10 

job = job_types[job_type]() 
job.do_job(uni_var) 

地獄,如果作業不保持狀態,他們不應該是類,但功能,而不是。

def job_a(arg): 
    ... 

def job_b(arg): 
    ... 

job = job_types[job_type] 
job(uni_var) 
1

你實際上沒有使用繼承所有在你原來的代碼,你的代碼中包含一個嚴重的錯誤,但口罩它出現。

您創建的superClass一個實例,它存儲job_typeuni_var,然後要麼實例化或option1option2商店,一個參考。 「子類」初始化時沒有數據(因此它們沒有job_typeuni_var屬性,並且必須覆蓋__init__以避免錯誤)。

當您致電job_select.job(...),superClass明確授權其job_choice屬性。所以沒有有用的繼承;你已經在你的子類覆蓋約superClass的一切,而不是job_select是取決於job_type和使用方法解析調用正確的代碼不同的子類的實例,job_select總是superClass它包含一個option1option2並明確代表它。

我提到的嚴重錯誤:既沒有option1也沒有option2實際上包含任何有關工作的信息,所以他們的job方法不能做任何有趣的事情。你打電話print uni_var,這是行不通的(通常是print self.uni_var得到uni_var這個工作),但似乎工作因爲你有一個全球性的叫uni_var。只要你開始做更復雜的事情,這個計劃就會嚴重倒閉。

@ srgerg的回答是一個很好的例子,說明如何使用繼承和工廠函數來解決您的問題。 @ CatPlusPlus的答案就是一個很好的例子,說明如何在這個例子中爲非常簡單的代碼使用更合適的工具(如果您的真實需求目前比較複雜,可能不是您需要的)。

+0

謝謝你的詳細解釋和建議,我也很擔心。實際的代碼在每個子類中都有很多定義,所以我認爲採用Factory方法可能更可取,儘管我目前對Factor方法或使用super()一無所知,所以我會閱讀那些。感謝大家的幫助。 – user788462