Python super()はTypeErrorを発生させます


109

Python 2.5では、次のコードでaが発生しTypeErrorます。

>>> class X:
      def a(self):
        print "a"

>>> class Y(X):
      def a(self):
        super(Y,self).a()
        print "b"

>>> c = Y()
>>> c.a()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in a
TypeError: super() argument 1 must be type, not classobj

をに置き換えるclass Xclass X(object)、機能します。これの説明は何ですか?


3
あなたの「しかし、私はクラスXをクラスX(オブジェクト)に置き換える」が私の問題を修正しました!thanx
AliBZ 2013年

回答:


132

その理由は、ということであるsuper()だけで動作する新しいスタイルのクラス 2.xシリーズ手段でから延びます、object

>>> class X(object):
        def a(self):
            print 'a'

>>> class Y(X):
        def a(self):
            super(Y, self).a()
            print 'b'

>>> c = Y()
>>> c.a()
a
b

4
これはどのPythonバージョンからデフォルトの動作になりましたか?
Geoの

6
2.2は新しいスタイルのクラスが導入されたときであり、3.0はそれらがデフォルトになった場所です。
Cody Brocious

7
@tsunamiスーパークラスに参加したい場合は、「Xa(self)」を実行してください
James Brady

あなたは私を誤解したと思います。三連祭壇画。私は3.0より前のバージョンのpythonを使用していたことを覚えており、私のクラスがObjectから継承していることを明確に述べておらず、superへの呼び出しはうまくいきました。多分それは2.6からのデフォルトの動作ですか?ただ言って:)
Geo

アラバスター、本当にその必要はありません。新しいスタイルのクラスには、スーパーだけでなく、多くのメリットがあります。古いスタイルの方法を宣伝しないでください。
Cody Brocious

14

さらに、必要がない限り、super()を使用しないでください。疑わしいかもしれない新しいスタイルのクラスを行うのは、汎用の「正しいこと」ではありません。

多重継承を期待していて、それを必要とする場合がありますが、MROの詳細がわかるまでは、MROをそのままにしておき、次のようにしてください。

 X.a(self)

2
私の6か月のPython / Djangoで「一般的に正しいこと」としてsuperを使用してきたので、それは正しいですか?
philgo20 2010

1
まあそれはそれ自体で単一の継承のためにあなたを傷つけることはありません(それが少し遅いことを除いて)、それはあなた自身にもあなたに何も得ません。__init__明確かつ賢明な方法で引数を渡すために、多重継承(特に)が必要なメソッドを設計する必要があります。そうしないと、誰かがクラスを使用して多重継承しようとしたときにTypeErrorsまたはより悪いデバッグ問題が発生します。この方法でMIをサポートするように実際に設計した場合(かなりトリッキーです)を除いsuperて、メソッドがMIセーフであることを暗示するのは避けた方がよいでしょう。
ボビンス

3

上記の回答のいずれも明確に言及していない場合。親クラスは「オブジェクト」から継承する必要があります。これにより、本質的に新しいスタイルクラスに変わります。

# python 3.x:
class ClassName(object): # This is a new style class
    pass

class ClassName: # This is also a new style class ( implicit inheritance from object )
    pass

# Python 2.x:
class ClassName(object): # This is a new style class
    pass

class ClassName:         # This is a old style class
    pass

申し訳ありませんが、Python 3.xでは、2番目の例(暗黙の継承)は、言及された問題のコンテキストでは実際には機能しません。
ソフロス

1

さまざまなXa()メソッドを試しました。ただし、a()を実行するにはXのインスタンスが必要なようなので、少なくとも私が遭遇したアプリケーションでは、X()。a(self)を実行しました。これは、以前の回答よりも完全なようです。不必要な構築と破壊があるので、問題を処理する良い方法ではないようですが、問題なく動作します。

私の特定のアプリケーションはPythonのcmd.Cmdモジュールでした。これは明らかに何らかの理由でNewStyleオブジェクトではありません。

最終結果:

X().a(self)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.