web-dev-qa-db-ja.com

super()がエラーで失敗します:親がオブジェクトを継承しない場合、TypeError "引数1はclassobjではなく型でなければなりません"

理解できないエラーが発生します。サンプルコードのどこに問題があるのでしょうか。

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'組み込みメソッドのヘルプからサンプルテストコードを取得しました。クラス「C」は

エラーは次のとおりです。

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)
 |
180
Ehsan Foroughi

あなたの問題は、クラスBが「新しいスタイル」のクラスとして宣言されていないことです。次のように変更します。

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では、この問題は発生しません。

300
steveha

また、クラスBを変更できない場合は、多重継承を使用してエラーを修正できます。

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

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

print C().meth(1)
134
frmdstryr

pythonバージョンが3.Xであれば、問題ありません。

あなたのpythonバージョンは2.Xだと思います、このコードを追加するとスーパーが動作します

__metaclass__ = type

コードは

__metaclass__ = type
class B:
    def meth(self, arg):
        print arg
class C(B):
    def meth(self, arg):
        super(C, self).meth(arg)
print C().meth(1)
16
yanghaogn

また、python 2.7を使用したときに投稿された問題に直面しました。 python 3.4では非常にうまく機能しています。

python 2.7で機能させるために、プログラムの上部に__metaclass__ = type属性を追加しましたが、機能しました。

__metaclass__:古いスタイルのクラスと新しいスタイルのクラスからの移行を容易にします。

3
JON