1. ホーム
  2. python

[解決済み] super() は、新しいスタイルのクラスに対して "TypeError: must be type, not classobj" を送出する。

2022-02-09 12:42:19

質問

の次のような使い方があります。 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

StackOverflowにも同様の質問があります。 Python super() は TypeError を発生させます。 このエラーは、ユーザークラスが新スタイルのクラスでないことが原因であると説明されています。 しかし、上記のクラスは、以下のクラスを継承しているため、新スタイルのクラスです。 object :

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

何が足りないのだろう?どうすれば super() ということでしょうか?

使用方法 HTMLParser.__init__(self) の代わりに super(TextParser, self).__init__() はうまくいくのですが、TypeErrorを理解したいのです。

追記:Joachimは、新しいスタイルクラスのインスタンスであることは、新しいスタイルクラスのインスタンスであることと同等ではないことを指摘しました。 object . 私は何度も反対のことを読んだので、混乱してしまいました(新スタイルのクラスインスタンスのテスト例で object インスタンステストです。 https://stackoverflow.com/revisions/2655651/3 ).

解決方法は?

さてさて、いつもの"です。 super() は旧式のクラスで使用できません"。

ただし、重要なのは 正しいテスト これは新しいスタイルなのか? インスタンス (つまり、オブジェクト)?"です。

>>> class OldStyle: pass
>>> instance = OldStyle()
>>> issubclass(instance.__class__, object)
False

となっており、(質問のように)なっていない。

>>> isinstance(instance, object)
True

について クラス であれば、正しい "is this a new-style class" のテストは。

>>> issubclass(OldStyle, object)  # OldStyle is not a new-style class
False
>>> issubclass(int, object)  # int is a new-style class
True

肝心な点 は、古いスタイルのクラスでは クラス インスタンスとその タイプ は区別されます。ここで OldStyle().__class__OldStyle を継承していない object 一方 type(OldStyle())instance タイプで、これは する を継承しています。 object . 基本的に、古いスタイルのクラスは、ただ単に instance (一方、新スタイルのクラスは、クラス自身を型とするオブジェクトを作成します)。このためか、インスタンス OldStyle()object : その type() を継承しています。 object (そのクラスが行うのは ではなく を継承しています。 object はカウントされません: 古いスタイルのクラスは、単に instance ). 部分的に参照する。 https://stackoverflow.com/a/9699961/42973 .

追記:新スタイルのクラスと旧スタイルのクラスの違いも一緒に見ることができます。

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

(旧式のクラスは ではなく 型であるため、そのインスタンスの型になることはできません)。