web-dev-qa-db-fra.com

Python super () déclenche TypeError

Dans Python 2.5, le code suivant lève un 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

Si je remplace le class X Par class X(object), cela fonctionnera. Quelle en est l'explication?

106
Geo

La raison en est que super() ne fonctionne que sur classes de nouveau style , ce qui dans la série 2.x signifie s'étendre de 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
129
Cody Brocious

De plus, n'utilisez pas super () sauf si vous y êtes obligé. Ce n'est pas la "bonne chose" à usage général à faire avec des classes de nouveau style que vous pourriez soupçonner.

Il y a des moments où vous vous attendez à un héritage multiple et vous pourriez le vouloir, mais jusqu'à ce que vous connaissiez les détails velus du MRO, laissez-le tranquille et respectez:

 X.a(self)
14
bobince

Dans le cas où aucune des réponses ci-dessus ne le mentionne clairement. Votre classe parente doit hériter de "object", ce qui la transformerait essentiellement en une nouvelle classe de style.

# 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
3
Abhi Tk

J'ai essayé les différentes méthodes X.a (); cependant, ils semblent nécessiter une instance de X pour effectuer un (), donc j'ai fait X (). a (self), ce qui semble plus complet que les réponses précédentes, au moins pour les applications que j'ai rencontrées. Cela ne semble pas être un bon moyen de gérer le problème car il y a une construction et une destruction inutiles, mais cela fonctionne bien.

Mon application spécifique était le module cmd.Cmd de Python, qui n'est évidemment pas un objet NewStyle pour une raison quelconque.

Résultat final:

X().a(self)
1
weberc2