2016-01-24 53 views
1

我想從父類繼承類構造函數。在嘗試了幾個關於堆棧溢出的建議之後,我想我會自己問一個問題,試圖理解1)爲什麼這個代碼是錯誤的,以及2)如何糾正它?Python中的繼承:類型錯誤,錯誤的參數數

的父類:

class Submit_Copasi_Job(object): 
    ''' 
    Submit a properly formatted copasi file to sun grid engine 
    ''' 
    def __init__(self,copasi_file,report_name): 
     self.copasi_file=copasi_file 
     self.copasiML_str=self._read_copasiML_as_string() 
     self.report_name=report_name 
     self.submit_copasi_job_SGE() 

    def _read_copasiML_as_string(self): 
     ''' 
     Read a copasiML file as string 
     ''' 
     assert os.path.exists(self.copasi_file), "{} does not exist!".format(self.copasi_file) 
     with open(self.copasi_file) as f: 
      fle = f.read() 
     return fle 

     .... 

子類(嘗試使用super(SubClass, self).__init__(...),但很明顯,我有什麼錯)

class Submit_Copasi_Multijob(Submit_Copasi_Job): 
    def __init__(self): 
     super(Submit_Copasi_Multijob,self).__init__(copasi_file,report_name) 

    def test(self): 
     return self.copasi_file 

運行代碼

fle='D:\\MPhil\\Model_Building\\Models\\TGFB\\Fli1_Models\\M7.cps' 
s=Submit_Copasi_Multijob(fle,'rep.txt') 
print s.test() 

我的全部迄今爲止的嘗試導致了類似的錯誤:

s=Submit_Copasi_Multijob(fle,'rep') 

TypeError: __init__() takes exactly 1 argument (3 given) 
+2

查看'Submit_Copasi_Multijob'的'__init__'方法...'copasi_file'和'report_name'定義在哪裏?你忘了添加參數。 – Bakuriu

+0

@Bakuriu是的,就是這樣。謝謝。如果你在下面寫一個答案,我會接受。 – CiaranWelsh

回答

2

問題是您的子類的__init__方法只接受一個參數,該參數將由Python自動提供,作爲對新創建對象的引用。所以,當你實例化一個Submit_Copasi_Multijob對象,你可以不提供任何參數,即這樣你的代碼目前正在編寫實例化的子類的對象正確的做法是

new_obj = Submit_Copasi_Multijob() 

當然,在執行__init__這將失敗因爲名稱copasi_filereport_name不會被定義。

修復此通過讓孩子級的__init__方法取三個參數,而不是一個:

def __init__(self, compasi_file, report_name): 
    super(Submit_Copasi_Multijob,self).__init__(copasi_file,report_name) 
    # other stuff 

但是,如果這是你曾經計劃在孩子的__init__方法做的唯一的事情(即沒有0​​),不需要覆蓋基類的__init__方法。在這種情況下,只需在Submit_Copasi_Multijob中省略__init__的定義。

+0

嗨timgeb,只是爲了澄清,如果我只有'copasi_file'和'report_name'參數在我的子類中,我根本不需要構造函數? – CiaranWelsh

+2

@ user3059024是的,取決於你想要做什麼。如果您在子類中省略了__init__的定義,它將繼承基類中的__init__。如果子類的__init__方法應該與基類的__init__方法完全相同,那麼就不需要在子類中重新定義__init__。 – timgeb