1. ホーム
  2. python

[解決済み】super()がエラーで失敗する。親がオブジェクトを継承していない場合、TypeError "argument 1 must be type, not classobj" が発生する。

2022-02-12 15:42:12

質問

原因不明のエラーが発生します。私のサンプルコードのどこが問題なのか、何か手がかりはありませんか?

class B:
    def meth(self, arg):
        print arg

class C(B):
    def meth(self, arg):
        super(C, self).meth(arg)

print C().meth(1)

サンプルテストは、組み込みメソッド「super」のヘルプから取得しました。

以下はそのエラーです。

Traceback (most recent call last):
  File "./test.py", line 10, in ?
    print C().meth(1)
  File "./test.py", line 8, in meth
    super(C, self).meth(arg)
TypeError: super() argument 1 must be type, not classobj

参考までに、python自体のhelp(super)はこちら。

Help on class super in module __builtin__:

class super(object)
 |  super(type) -> unbound super object
 |  super(type, obj) -> bound super object; requires isinstance(obj, type)
 |  super(type, type2) -> bound super object; requires issubclass(type2, type)
 |  Typical use to call a cooperative superclass method:
 |  class C(B):
 |      def meth(self, arg):
 |          super(C, self).meth(arg)
 |

解決方法は?

あなたの問題は、クラスBが"new-style"クラスとして宣言されていないことです。 このように変更してください。

class B(object):

と入力すれば、動作します。

super() といったサブクラスやスーパークラスのようなものは、新スタイルのクラスでしか機能しません。 ということを常にタイプする習慣を身につけることをお勧めします。 (object) をクリックして、それが新スタイルのクラスであることを確認してください。

旧式のクラス(クラシッククラスとも呼ばれる)は、常にタイプ classobj 新スタイルのクラスは type . そのため、ご覧のようなエラーメッセージが表示されたのです。

TypeError: super() argument 1 must be type, not classobj

実際に試してみてください。

class OldStyle:
    pass

class NewStyle(object):
    pass

print type(OldStyle)  # prints: <type 'classobj'>

print type(NewStyle) # prints <type 'type'>

Python 3.xでは、すべてのクラスがニュースタイルであることに注意してください。旧スタイルのクラスの構文はそのまま使えますが、新スタイルのクラスを手に入れることができます。ですから、Python 3.xでは、この問題は発生しません。