本文翻譯自: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
的執行個體。