下面使用super()会引发TypeError:为什么?
>>> from HTMLParser import HTMLParser
>>> class TextParser(HTMLParser):
... def __init__(self):
... super(TextParser, self).__init__()
... self.all_data = []
...
>>> TextParser()
(...)
TypeError: must be type, not classobj
在StackOverflow上也有类似的问题:Python super()引发TypeError,其中错误是由用户类不是新样式类这一事实解释的。然而,上面的类是一个新型的类,因为它继承自object:
>>> isinstance(HTMLParser(), object)
True
我错过了什么?我如何使用super(),在这里?
使用HTMLParser.__init__(self)而不是super(TextParser, self).__init__()将工作,但我想了解TypeError。
PS: Joachim指出,作为一个新型的类实例并不等同于一个对象。我读过很多次相反的文章,因此感到困惑(基于对象实例测试的新型类实例测试示例:https://stackoverflow.com/revisions/2655651/3)。
Super()只能在新型类中使用,这意味着根类需要从'object'类继承。
例如,顶级类需要是这样的:
class SomeClass(object):
def __init__(self):
....
not
class SomeClass():
def __init__(self):
....
所以,解决方案是直接调用父类的init方法,像这样:
class TextParser(HTMLParser):
def __init__(self):
HTMLParser.__init__(self)
self.all_data = []
问题是super需要一个对象作为祖先:
>>> class oldstyle:
... def __init__(self): self.os = True
>>> class myclass(oldstyle):
... def __init__(self): super(myclass, self).__init__()
>>> myclass()
TypeError: must be type, not classobj
仔细观察就会发现:
>>> type(myclass)
classobj
But:
>>> class newstyle(object): pass
>>> type(newstyle)
type
所以你的问题的解决方案是继承对象以及从HTMLParser。
但是要确保object在MRO类中排在最后:
>>> class myclass(oldstyle, object):
... def __init__(self): super(myclass, self).__init__()
>>> myclass().os
True
Super()只能在新型类中使用,这意味着根类需要从'object'类继承。
例如,顶级类需要是这样的:
class SomeClass(object):
def __init__(self):
....
not
class SomeClass():
def __init__(self):
....
所以,解决方案是直接调用父类的init方法,像这样:
class TextParser(HTMLParser):
def __init__(self):
HTMLParser.__init__(self)
self.all_data = []