super() 引发“TypeError: must be type, not classobj";新式班级 [英] super() raises "TypeError: must be type, not classobj" for new-style class
问题描述
super()
的以下使用会引发 TypeError:为什么?
StackOverflow 上有一个类似的问题:Python super() raises TypeError,其中错误是由用户类不是新式类这一事实来解释的.然而,上面的类是一个新式类,因为它继承自object
:
我错过了什么?我如何在这里使用 super()
?
使用 HTMLParser.__init__(self)
而不是 super(TextParser, self).__init__()
会起作用,但我想了解 TypeError.>
PS:Joachim 指出,作为新式类实例并不等同于成为 object
.我多次阅读相反的内容,因此我感到困惑(基于 object
实例测试的新型类实例测试示例:https://stackoverflow.com/revisions/2655651/3).
好吧,这是通常的super()
不能与旧式类一起使用".
然而,重要的一点是正确的测试这是一个新型的实例(即对象)吗?"是
<预><代码>>>>类 OldStyle:通过>>>实例 = OldStyle()>>>issubclass(instance.__class__, object)错误的而不是(如问题中所述):
<预><代码>>>>isinstance(实例,对象)真的对于类,正确的这是一个新式类"测试是:
<预><代码>>>>issubclass(OldStyle, object) # OldStyle 不是新式类错误的>>>issubclass(int, object) # int 是一个新式类真的关键点是旧式类,实例的类和它的类型是不同的.这里的OldStyle().__class__
是OldStyle
,它不继承自object
,而type(OldStyle())
code> 是 instance
类型,它确实继承自 object
.基本上,旧式类只创建 instance
类型的对象(而新式类创建类型为类本身的对象).这可能就是实例 OldStyle()
是一个 object
的原因:它的 type()
继承自 object
(它的类不从object
继承这一事实不算数:旧式类只是构造instance
类型的新对象).部分参考:https://stackoverflow.com/a/9699961/42973.
PS:新式类和旧式类的区别也可以通过以下方式看出:
<预><代码>>>>type(OldStyle) # OldStyle 创建对象但本身不是类型类对象>>>isinstance(OldStyle, 类型)错误的>>>type(int) # 一个新样式的类是一个类型类型(旧式类是不是类型,因此它们不能是其实例的类型).
The following use of super()
raises a TypeError: why?
>>> 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. However, the class above is a new-style class, as it inherits from object
:
>>> isinstance(HTMLParser(), object)
True
What am I missing? How can I use super()
, here?
Using HTMLParser.__init__(self)
instead of super(TextParser, self).__init__()
would work, but I would like to understand the TypeError.
PS: Joachim pointed out that being a new-style-class instance is not equivalent to being an 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).
Alright, it's the usual "super()
cannot be used with an old-style class".
However, the important point is that the correct test for "is this a new-style instance (i.e. object)?" is
>>> class OldStyle: pass
>>> instance = OldStyle()
>>> issubclass(instance.__class__, object)
False
and not (as in the question):
>>> isinstance(instance, object)
True
For classes, the correct "is this a new-style class" test is:
>>> issubclass(OldStyle, object) # OldStyle is not a new-style class
False
>>> issubclass(int, object) # int is a new-style class
True
The crucial point is that with old-style classes, the class of an instance and its type are distinct. Here, OldStyle().__class__
is OldStyle
, which does not inherit from object
, while type(OldStyle())
is the instance
type, which does inherit from object
. Basically, an old-style class just creates objects of type instance
(whereas a new-style class creates objects whose type is the class itself). This is probably why the instance OldStyle()
is an object
: its type()
inherits from object
(the fact that its class does not inherit from object
does not count: old-style classes merely construct new objects of type instance
). Partial reference: https://stackoverflow.com/a/9699961/42973.
PS: The difference between a new-style class and an old-style one can also be seen with:
>>> type(OldStyle) # OldStyle creates objects but is not itself a type
classobj
>>> isinstance(OldStyle, type)
False
>>> type(int) # A new-style class is a type
type
(old-style classes are not types, so they cannot be the type of their instances).
这篇关于super() 引发“TypeError: must be type, not classobj";新式班级的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!