天天看點

對于新式類,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

的執行個體。