web-dev-qa-db-fra.com

Python comportement super () non fiable

Pour une raison quelconque, la méthode super() ne se comporte pas toujours comme prévu, choisissant de retourner:

TypeError('super(type, obj): obj must be an instance or subtype of type)'

Je comprends ce que l'erreur signifie. Je ne comprends pas pourquoi cela apparaît comme une erreur. Voici l'extrait de code qui se casse. Tous les objets du système sont de nouveaux objets de style.

Ce qui est vraiment intéressant, c'est que cette erreur n'apparaît pas toujours. Je ne sais pas ce qui en est la cause. La méthode super() dans Retrieval transmet la classe Retrieval, puis elle-même en tant qu'objet, qui est, à ma connaissance, exactement comment super() est supposé à appeler.

Des pensées?

Dans le fichier DBConnection.py:

class DBAdminConnection(object):
    def __init__(self):
        self.user = DBUserConnection().user 
        self.submissions = DBSubmissionConnection()

Dans le fichier Retrieval.py

class Retrieval(DBConnection.DBAdminConnection): 
    def __init__(self, username=None, password=None, unique_key=None):
        super(Retrieval,self).__init__()
        if username and password:
            self.username = username
            self.user.login(username,password, config.DATABASE)
            if self.user.error:
                raise UserLoginError(username)
        self.unique_key = unique_key
41
Thomas Thorogood

Rechargez-vous des modules d'une manière ou d'une autre au milieu des choses? Si c'est le cas, cela peut expliquer cette erreur.

isinstance(self,DBAdminConnection) peut devenir faux après le rechargement des modules en raison des modifications des références de mémoire, apparemment.

Modifier: si vous exécutez votre application web.py sous mod_wsgi, assurez-vous de désactiver le chargement automatique:

app = web.application(urls, globals(), autoreload=False)
57
Eduardo Ivanec

Si vous utilisez reload () dans le cadre de votre flux de travail, vous devez apparemment également utiliser super(self.__class__, self).__init__ pour l'initialisation de l'héritage.

Je suppose que vous constaterez que ce bogue coïncide avec l'échec de id(self.__class__) ==id(Retrieval).

12
Hal Meyers

J'ai juste eu le même problème, en exécutant mon code dans le cahier jupyter. J'utilisais le rechargement, j'ai donc redémarré mon noyau pour suivre la réponse d'Eduardo Ivanec pour essayer de voir si c'était le problème. Puis mon code s'est cassé. J'ai découvert que mon problème était lié à plusieurs couches d'héritage, où la couche inférieure était définie ci-dessus la deuxième couche inférieure du module.

class MyClass1(object):
'''example class 1'''

class MyClass2(MyClass1):
'''example class 2'''
    def __init__(self):
    super(MyClass2, self).__init__()

class MyClass4(MyClass3):
'''example class 4 - no __init__ definition'''

class MyClass3(MyClass2):
'''example class 3 - no __init__ definition'''

Lorsque j'ai déplacé MyClass4 sous MyClass3, cela a résolu le problème.

C'est probablement une erreur de débutant, donc cela ne résoudra probablement pas la cause du problème d'origine ci-dessus, mais j'ai pensé que je posterais au cas où d'autres recrues, comme moi, commettraient la même erreur.

(Toutes mes excuses si mon style est incorrect, c'est mon premier post sur Stack Overflow. :))

1
ahnastin

Je ne sais pas pourquoi l'erreur se produit, mais pour faciliter le débogage, vous pouvez encapsuler l'appel à super dans un try/except bloque et effectue un vidage des données lorsque l'exception est levée. Quelque chose comme ça:

class Retrieval(DBConnection.DBAdminConnection): 
    def __init__(self, username=None, password=None, unique_key=None):
        try:
            super(Retrieval,self).__init__()
        except TypeError, e:
            print "Failure initialising Retrieval --> self: %r"
            raise
        if username and password:
            self.username = username
            self.user.login(username,password, config.DATABASE)
            if self.user.error:
                raise UserLoginError(username)
        self.unique_key = unique_key
1
Ethan Furman

J'ai eu la même erreur, puis j'ai remarqué que j'avais une classe en double (mon erreur) dans le même fichier.py. L'erreur a disparu lorsque j'ai renommé la deuxième classe A en classe B

#Just some example below, not real code
class A (object):

    def fun(self):
        super(A, self).fun()

class A (object): ##This second class with same name (A) caused the error

   def some_fun(self,x,y):
1
Bernard Too