對於新式類,super()引發“TypeError:必須是type,而不是classobj”

本文翻譯自:super() raises “TypeError: must be type, not classobj” for new-style class

The following use of super() raises a TypeError: why? 以下使用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

There is a similar question on StackOverflow: Python super() raises TypeError , where the error is explained by the fact that the user class is not a new-style class. StackOverflow上有一個類似的問題: Python super()引發TypeError ,其中錯誤的解釋是用戶類不是新式類。 However, the class above is a new-style class, as it inherits from object : 但是,上面的類是一個新式類,因爲它繼承自object

>>> isinstance(HTMLParser(), object)
True

What am I missing? 我錯過了什麼? How can I use super() , here? 我怎麼能在這裏使用super()

Using HTMLParser.__init__(self) instead of super(TextParser, self).__init__() would work, but I would like to understand the TypeError. 使用HTMLParser.__init__(self)而不是super(TextParser, self).__init__()可以工作,但我想了解TypeError。

PS: Joachim pointed out that being a new-style-class instance is not equivalent to being an object . PS:Joachim指出,作爲一個新式的實例並不等同於成爲一個object I read the opposite many times, hence my confusion (example of new-style class instance test based on object instance test: https://stackoverflow.com/revisions/2655651/3 ). 我多次反覆閱讀,因此我的困惑(基於object實例測試的新式類實例測試示例: https//stackoverflow.com/revisions/2655651/3 )。


#1樓

參考:https://stackoom.com/question/eh3G/對於新式類-super-引發-TypeError-必須是type-而不是classobj


#2樓

You can also use class TextParser(HTMLParser, object): . 您還可以使用class TextParser(HTMLParser, object): This makes TextParser a new-style class, and super() can be used. 這使得TextParser成爲一種新式的類,並且可以使用super()


#3樓

the correct way to do will be as following in the old-style classes which doesn't inherit from 'object' 正確的方法是在舊式類中繼承“對象”

class A:
    def foo(self):
        return "Hi there"

class B(A):
    def foo(self, name):
        return A.foo(self) + name

#4樓

The problem is that super needs an object as an ancestor: 問題是super需要一個object作爲祖先:

>>> 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

On closer examination one finds: 仔細研究後發現:

>>> type(myclass)
classobj

But: 但:

>>> class newstyle(object): pass

>>> type(newstyle)
type    

So the solution to your problem would be to inherit from object as well as from HTMLParser. 因此,您的問題的解決方案是從對象以及HTMLParser繼承。 But make sure object comes last in the classes MRO: 但要確保對象在MRO類中排在最後:

>>> class myclass(oldstyle, object):
...     def __init__(self): super(myclass, self).__init__()

>>> myclass().os
True

#5樓

FWIW and though I'm no Python guru I got by with this FWIW雖然我不是Python大師,但我還是接受了這個

>>> class TextParser(HTMLParser):
...    def handle_starttag(self, tag, attrs):
...        if tag == "b":
...            self.all_data.append("bold")
...        else:
...            self.all_data.append("other")
...     
...         
>>> p = TextParser()
>>> p.all_data = []
>>> p.feed(text)
>>> print p.all_data
(...)

Just got me the parse results back as needed. 剛剛根據需要解析瞭解析結果。


#6樓

If you look at the inheritance tree (in version 2.6), HTMLParser inherits from SGMLParser which inherits from ParserBase which doesn't inherits from object . 如果查看繼承樹(在2.6版本中), HTMLParser繼承自從ParserBase繼承的SGMLParser ,它object繼承。 Ie HTMLParser is an old-style class. 即HTMLParser是一箇舊式的類。

About your checking with isinstance , I did a quick test in ipython: 關於你的isinstance ,我在ipython中做了一個快速測試:

In [1]: class A:
   ...:     pass
   ...: 

In [2]: isinstance(A, object)
Out[2]: True

Even if a class is old-style class, it's still an instance of object . 即使一個類是舊式類,它仍然是一個object的實例。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章