2009-04-27 14 views
5

共享共同父类的一组类的初始化过程可以分为三部分:公共部分1,类特定部分,公共部分2。目前,前两个部分是从各子类的__init__函数调用,但第二公共部分必须单独 打了个比方:如何在继承的Python类中执行常见的后期初始化任务?

class BaseClass: 
    def __init__(self): 
    print 'base __init__' 
    self.common1() 

    def common1(self): 
    print 'common 1' 

    def finalizeInitialization(self): 
    print 'finalizeInitialization [common2]' 


class Subclass1(BaseClass): 
    def __init__(self): 
    BaseClass.__init__(self) 
     self.specific() 

    def specific(self): 
    print 'specific' 


if __name__ == '__main__': 
    s = Subclass1() #Don't forget to finalize the initialization 
    s.finalizeInitialization() # now the object is fully initialized 

有没有办法不具有调用finalizeInitialization() ?

编辑可以将调用finalizeInitialization()转移到Subclass1的__init__中(如S.Lott's answer)。这使得生活更轻松,但仍需要记住完成初始化,这次是在“构造函数”中。无论哪种方式,都无法执行完整的初始化,这正是我正在寻找的。

回答

6

版本1 - 委托一切。

class Subclass1(BaseClass): 
    def __init__(self): 
     super(Subclass1, self).__init__() 
     self.specific() 
     super(Subclass1, self).finalizeInitialization() 

第2版 - 代表只需一个步骤

class BaseClass: 
    def __init__(self): 
     print 'base __init__' 
     self.common1() 
     self.specific() 
     self.finalizeInitialization() 

    def common1(self): 
     print 'common 1' 

    def finalizeInitialization(self): 
     print 'finalizeInitialization [common2]' 

    def specific(self): 
     # two choices: 
     # if this is "abstract": raise an exception 
     # if this is "concrete": pass 
+0

谢谢,但请参阅我的编辑进行澄清 – 2009-04-27 20:59:54

0

出了什么问题从子类的init调用finalInitilazation?

class BaseClass: 
     def __init__(self): 
      print 'base __init__' 
      self.common1() 

     def common1(self): 
      print 'common 1' 

     def finalizeInitialization(self): 
      print 'finalizeInitialization [common2]' 


    class Subclass1(BaseClass): 
     def __init__(self): 
      BaseClass.__init__(self) 
      self.specific() 
      BaseClass.finalizeInitialization(self) 

     def specific(self): 
      print 'specific' 


    if __name__ == '__main__': 
     s = Subclass1() #Don't forget to finalize the initialization 
     s.finalizeInitialization() # now the object is fully initialized 
0

如果您必须以特定顺序调用多个方法,通常意味着设计出现问题(它泄漏了实现细节)。所以我会尽力为此工作。

另一方面,如果人们从班级派生并且必须修改初始化,他们应该意识到这些影响 - 这不是您希望在普通API中使用的内容。或者,你可能对最后的初始化有所防范,并检查它是否在依赖它的方法中被调用(如果没有的话,调用它或引发异常)。

10

模板方法设计模式来救援:

class BaseClass: 
    def __init__(self, specifics=None): 
     print 'base __init__' 
     self.common1() 
     if specifics is not None: 
      specifics() 
     self.finalizeInitialization() 

    def common1(self): 
     print 'common 1' 

    def finalizeInitialization(self): 
     print 'finalizeInitialization [common2]' 


class Subclass1(BaseClass): 
    def __init__(self): 
     BaseClass.__init__(self, self.specific) 

    def specific(self): 
     print 'specific' 
1

类似S.洛特的方法,只是没有派生类重写(甚至调用)的常用方法方式(短覆盖__init__的) :

class BaseClass: 
    def __init__(self): 
     def common(): 
      print "common initialization..." 

     def final(): 
      print "common finalization..." 

     common() 
     self.specific() 
     final() 

    def final_init(self): 
     print "BaseClass.final_init" 


class Subclass1(BaseClass): 

    def specific(self): 
     print "Subclass1.specific" 

您可能想提供的specific的默认实现在BaseClass如果不是没关系,当你创建一个不任何子类的实例来引发AttributeError提供自己的实现。