关于继承:python super()引发typeerror

Python super() raises TypeError

在python 2.5中,以下代码引发一个TypeError

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
>>> class X:
      def a(self):
        print"a"

>>> class Y(X):
      def a(self):
        super(Y,self).a()
        print"b"

>>> c = Y()
>>> c.a()
Traceback (most recent call last):
  File"<stdin>", line 1, in <module>
  File"<stdin>", line 3, in a
TypeError: super() argument 1 must be type, not classobj

如果我用class X(object)替换class X,它就会工作。对此有什么解释?


原因是super()只在新类型的类上运行,在2.x系列中,这意味着从object扩展:

1
2
3
4
5
6
7
8
9
10
11
12
13
>>> class X(object):
        def a(self):
            print 'a'

>>> class Y(X):
        def a(self):
            super(Y, self).a()
            print 'b'

>>> c = Y()
>>> c.a()
a
b


此外,除非必须使用super(),否则不要使用super()。对于您可能怀疑的新样式类,这不是一个通用的"正确的事情"。

有时,您可能希望继承多个遗产,但在您了解MRO的毛茸茸的细节之前,最好不要管它,坚持:

1
 X.a(self)


如果上述答案都没有明确提及。您的父类需要从"object"继承,这实际上会将其转换为一个新的样式类。

1
2
3
4
5
6
7
8
9
10
11
12
13
# python 3.x:
class ClassName(object): # This is a new style class
    pass

class ClassName: # This is also a new style class ( implicit inheritance from object )
    pass

# Python 2.x:
class ClassName(object): # This is a new style class
    pass

class ClassName:         # This is a old style class
    pass

我尝试了各种x.a()方法;但是,它们似乎需要x的一个实例来执行a(),所以我做了x().a(self),它看起来比以前的答案更完整,至少对于我遇到的应用程序来说。这似乎不是一个很好的解决问题的方法,因为有不必要的建设和破坏,但它工作得很好。

我的特定应用程序是python的cmd.cmd模块,由于某种原因,它显然不是NewStyle对象。

最终结果:

1
X().a(self)