super() は、新しいスタイルのクラスに対して「TypeError: type である必要があります。classobj ではありません」というエラーを発生させます。質問する

super() は、新しいスタイルのクラスに対して「TypeError: type である必要があります。classobj ではありません」というエラーを発生させます。質問する

次のように使用すると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 を理解したいと思います。

PS: Joachim は、新しいスタイルのクラス インスタンスであることは、 であることと同じではないと指摘しましたobject。私はその逆を何度も読んだので、混乱しました (インスタンス テストに基づく新しいスタイルのクラス インスタンス テストの例object:https://stackoverflow.com/revisions/2655651/3)。

ベストアンサー1

そうですね、いつもの「super()旧式のクラスでは使用できません」ですね。

しかし、重要な点は、「これは新しいスタイルのインスタンス(つまりオブジェクト)ですか?」という正しいテストは

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

そして(質問のように)そうではありません:

>>> isinstance(instance, object)
True

クラスの場合、「これは新しいスタイルのクラスであるかどうか」の正しいテストは次のとおりです。

>>> 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という事実は考慮されません。旧スタイルのクラスは 型の新しいオブジェクトを作成するだけです)。部分的な参照:objectinstancehttps://stackoverflow.com/a/9699961/42973

PS: 新しいスタイルのクラスと古いスタイルのクラスの違いは、次の例でも確認できます。

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

(旧スタイルのクラスは型ではないため、インスタンスの型にすることはできません)。

おすすめ記事