web-dev-qa-db-fra.com

super () échoue avec l'erreur suivante: TypeError "l'argument 1 doit être type, pas classobj" lorsque le parent n'hérite pas de l'objet

J'ai une erreur que je n'arrive pas à comprendre. Aucun indice sur ce qui ne va pas avec mon exemple de code?

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

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

print C().meth(1)

J'ai obtenu le code de test exemple à l'aide de la méthode "super" intégrée. La classe "C" est la

Voici l'erreur:

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

Pour votre information, voici l'aide (super) de python lui-même:

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

Votre problème est que la classe B n'est pas déclarée comme une classe de "nouveau style". Changez-le comme ça:

class B(object):

et ça va marcher.

super() et tous les sous-classes/super-classes ne fonctionnent qu'avec les classes de style nouveau. Je vous recommande de prendre l'habitude de toujours taper que (object) Dans n'importe quelle définition de classe pour vous assurer qu'il s'agit d'une classe d'un nouveau style.

Les classes de style ancien (également appelées classes "classiques") sont toujours du type classobj; Les classes new-style sont de type type. C'est pourquoi vous avez le message d'erreur que vous avez vu:

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

Essayez ceci pour voir par vous-même:

class OldStyle:
    pass

class NewStyle(object):
    pass

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

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

Notez que dans Python 3.x, toutes les classes ont un nouveau style. Vous pouvez toujours utiliser la syntaxe des classes de style ancien, mais vous obtenez une classe de style nouveau. Donc, dans Python 3.x, vous n'aurez pas ce problème.

300
steveha

De plus, si vous ne pouvez pas changer de classe B, vous pouvez corriger l'erreur en utilisant un héritage multiple.

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

Si la version python est 3.X), tout va bien.

Je pense que votre python est 2.X, le super fonctionnerait lors de l'ajout de ce code

__metaclass__ = type

donc le code est

__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

J'ai également été confronté au problème posté lorsque j'ai utilisé python 2.7. Il fonctionne très bien avec python 3.4

Pour le faire fonctionner dans python 2.7 j'ai ajouté le __metaclass__ = type attribut au sommet de mon programme et cela a fonctionné.

__metaclass__: Cela facilite la transition entre les classes de style ancien et les classes de style différent.

3
JON