Python扩展 – 使用超()蟒3与Python 2

本来我想问这个问题 ,但后来我发现它已经被认为之前…

谷歌search我发现这个扩展configparser的例子。 以下使用python 3:

$ python3 Python 3.2.3rc2 (default, Mar 21 2012, 06:59:51) [GCC 4.6.3] on linux2 >>> from configparser import SafeConfigParser >>> class AmritaConfigParser(SafeConfigParser): ... def __init_(self): ... super().__init__() ... >>> cfg = AmritaConfigParser() 

但不是用python2:

 >>> class AmritaConfigParser(SafeConfigParser): ... def __init__(self): ... super(SafeConfigParser).init() ... >>> cfg = AmritaConfigParser() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 3, in __init__ TypeError: must be type, not classob 

然后,我读了一下Python新类与旧类风格(例如, 在这里 ,现在我想知道,我可以这样做:

 class MyConfigParser(ConfigParser.ConfigParser): def Write(self, fp): """override the module's original write funcition""" .... def MyWrite(self, fp): """Define new function and inherit all others""" 

但是,我不应该调用init? 这是在Python 2中相当于:

  class AmritaConfigParser(ConfigParser.SafeConfigParser): #def __init__(self): # super().__init__() # Python3 syntax, or rather, new style class syntax ... # # is this the equivalent of the above ? def __init__(self): ConfigParser.SafeConfigParser.__init__(self) 

在此先感谢帮助我解决问题。

  • super() (不带参数)是在Python 3中引入的:

     super() -> same as super(__class__, self) 

    所以这将是新的类风格的Python 2等价物:

     super(CurrentClass, self) 
  • 对于老式的课程,你可以随时使用:

      class Classname(OldStyleParent): def __init__(self, *args, **kwargs): OldStyleParent.__init__(self, *args, **kwargs) 

在单个inheritance的情况下(当你只有一个类的子类时),你的新类inheritance了基类的方法。 这包括__init__ 。 所以,如果你没有在你的课堂上定义它,你会从基地获得。

如果你引入了多重inheritance(一次多于一个类的子类),事情就会变得复杂起来。 这是因为如果多个基类有__init__ ,你的类将只inheritance第一个。

在这种情况下,如果可以的话,你应该真的使用super ,我会解释为什么。 但并不总是你可以。 问题是所有的基类都必须使用它(以及它们的基类 – 整棵树)。

如果是这样的话,那么这也可以正常工作(在Python 3中,但是你可以把它重写成Python 2 – 它也有super ):

 class A: def __init__(self): print('A') super().__init__() class B: def __init__(self): print('B') super().__init__() class C(A, B): pass C() #prints: #A #B 

请注意,即使基类没有自己的基类,两个基类也是如何使用super

super是:它调用MRO中下一个类的方法(方法parsing顺序)。 C的MRO是: (C, A, B, object) 。 您可以打印C.__mro__以查看它。

所以, CAinheritance了__init__ ,并且在A.__init__调用了B.__init__B跟在MRO中)。

所以在C什么都不做,最后你俩都调用了,这就是你想要的。

现在,如果你不使用super ,你最终会inheritanceA.__init__ (和以前一样),但是这次没有任何东西会为你调用B.__init__

 class A: def __init__(self): print('A') class B: def __init__(self): print('B') class C(A, B): pass C() #prints: #A 

要解决你必须定义C.__init__

 class C(A, B): def __init__(self): A.__init__(self) B.__init__(self) 

问题在于,在更复杂的MI树中,一些类的__init__方法最终可能被多次调用,而super / MRO则保证它们只被调用一次。

总之,它们是等价的。 让我们有一个历史观点:

(1)起初,function看起来像这样。

  class MySubClass(MySuperClass): def __init__(self): MySuperClass.__init__(self) 

(2)使代码更抽象(更便携)。 一个常见的获得超级类的方法是这样发明的:

  super(<class>, <instance>) 

而init函数可以是:

  class MySubClassBetter(MySuperClass): def __init__(self): super(MySubClassBetter, self).__init__() 

然而,要求类和实例的明确传递会使DRY(不要重复自己)规则稍微有些落空。

(3)在V3中。 这更聪明,

  super() 

在大多数情况下是足够的。 你可以参考http://www.python.org/dev/peps/pep-3135/