super() 引发“TypeError: must be type, not classobj";新式班级 [英] super() raises "TypeError: must be type, not classobj" for new-style class

查看:35
本文介绍了super() 引发“TypeError: must be type, not classobj";新式班级的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

super() 的以下使用会引发 TypeError:为什么?

<预><代码>>>>从 HTMLParser 导入 HTMLParser>>>类 TextParser(HTMLParser):... def __init__(self):... super(TextParser, self).__init__()... self.all_data = []...>>>文本解析器()(……)类型错误:必须是类型,而不是 classobj

StackOverflow 上有一个类似的问题:Python super() raises TypeError,其中错误是由用户类不是新式类这一事实来解释的.然而,上面的类是一个新式类,因为它继承自object:

<预><代码>>>>isinstance(HTMLParser(),对象)真的

我错过了什么?我如何在这里使用 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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆