具有“超级”属性的Python单继承中的TypeError

时间:2014-01-11 14:06:56

标签: python

我从没想过Python 2.7 的继承是如此反人类。为什么以下代码会给我一个TypeError?

>>> class P:
...     def __init__(self, argp):
...         self.pstr=argp
... 
>>> class C(P):
...     def __init__(self, argp, argc):
...         super.__init__(self,argp)
...         self.cstr=argc
... 
>>> x=C("parent","child")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in __init__
TypeError: descriptor '__init__' requires a 'super' object but received a 'instance'

然后我改为这两个仍然含糊不清的错误:

>>> class C(P):
...     def __init__(self, argp, argc):
...         super().__init__(self,argp)
...         self.cstr=argc
... 
>>> x=C("parent", "child")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in __init__
TypeError: super() takes at least 1 argument (0 given)


>>> class C(P):
...     def __init__(self, argp, argc):
...         super(P).__init__(self,argp)
...         self.cstr=argc
... 
>>> x=C("parent", "child")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in __init__
TypeError: must be type, not classobj

-------- -------- ADD

它仍然无法正常工作。

>>> class P:
...     def __init__(self, argp):
...         self.pstr=argp
... 
>>> class C(P):
...     def __init__(self, arg1, arg2):
...         super(C, self).__init__(arg1)
...         self.cstr=arg2
... 
>>> z=C("PPP", "CCC")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in __init__
TypeError: must be type, not classobj

--------- ---------- ADD2

以下所有2个代码片段似乎都有效,有什么区别?顺便说一句,我何时应该使用新样式类旧样式类

>>> class C(P):
...     def __init__(self, argp, argc):
...         super(C,self).__init__(argp)   #<------ C and self
...         self.cstr=argc
... 
>>> class C(P):
...     def __init__(self, argp, argc):
...         super(P,C).__init__(argp)  #<----- P and C
...         self.cstr=argc

1 个答案:

答案 0 :(得分:16)

根据您正在使用的Python版本,您的问题可能有两种答案。

Python 2.x

super必须像(example for the doc)一样调用:

class C(B):
    def method(self, arg):
        super(C, self).method(arg)

在您的代码中,那将是:

>>> class P(object):    # <- super works only with new-class style
...     def __init__(self, argp):
...         self.pstr=argp
... 
>>> class C(P):
...     def __init__(self, argp, argc):
...         super(C, self).__init__(argp)
...         self.cstr=argc

在这种情况下,您也不必在参数中传递self

Python 3.x

在Python 3.x中,super方法得到了改进:你可以use it without any parameters(两者都是可选的)。此解决方案也可以工作,但仅限Python 3及更高版本:

>>> class C(P):
...     def __init__(self, argp, argc):
...         super().__init__(argp)
...         self.cstr=argc