2016-01-24 51 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