2012-03-15 11 views
40

Per qualche ragione, il metodo super() non sempre comporta come previsto, optando per tornare:Python super() non credibile

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

Capisco che cosa l'errore significa. Non capisco perché si presenta come un errore. Ecco il frammento di codice che si sta rompendo. Tutti gli oggetti nel sistema sono nuovi oggetti di stile.

Ciò che è veramente interessante è che questo errore non è sempre. Non so cosa lo stia causando. Il metodo in Retrieval passa la classe Retrieval e quindi se stesso come un oggetto, che è, per quanto ne so, esattamente come super() è supposto da invocare.

Qualche idea?

Nel file di DBConnection.py:

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

Nel file di 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 

risposta

57

Stai ricaricando i moduli in qualche modo nel mezzo delle cose? Se è così, questo potrebbe spiegare questo errore.

isinstance(self,DBAdminConnection) diventino false dopo ricaricare i pacchetti a causa delle modifiche ai riferimenti di memoria, apparentemente.

Edit: se si sta eseguendo il tuo web.py app sotto mod_wsgi, assicurarsi che si sta disabilitando autoreload:

app = web.application(urls, globals(), autoreload=False) 
+0

Si tratta di Webpy. Quindi questa è una possibilità definita. Tanto più che se uccido l'istanza dell'app e la respawn, il problema scompare. Wow. Ora la domanda diventa come diamine di aggiustarlo. –

+0

@TomThorogood: come stai gestendo la tua app? Stai usando mod_wsgi? –

+0

@TomThorogood: aggiunto qualcosa nel caso in cui si stia utilizzando wsgi. –

1

Non sono sicuro che il motivo per cui l'errore sta accadendo, ma come un aiuto alla debugging è possibile che la chiamata venga spostata su super in un blocco try/except e venga eseguito un dump di dati quando viene sollevata l'eccezione. Qualcosa di simile a questo:

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 
+0

Intendevi che non sei sicuro? Perché hai riposto le mie speranze per un momento./grin –

+0

@TomThorogood: Ack! Sì, volevo dire "non sono sicuro" - scusa! –

+0

haha. nessun problema! Grazie per la cosa. Ho un po 'di debug in atto; Stavo solo ripulendo il codice per SO. –

11

Se si utilizza reload() come parte del flusso di lavoro, è a quanto pare deve usare anche super(self.__class__, self).__init__ per l'inizializzazione eredità.

ho il sospetto si trova questo bug coincide con id(self.__class__) ==id(Retrieval) mancanza.

+8

'super (auto .__ class__, self)' è sempre sbagliato. Diventerà un ciclo infinito se si sottoclasse ulteriormente. – Blckknght

+1

Cosa succede se non si esegue la sottoclasse oltre, a volte è OK? – cce

1

Ho appena avuto lo stesso problema, eseguendo il mio codice in jupyter notebook. Stavo usando la ricarica, quindi ho riavviato il mio kernel per dare seguito alla risposta di Eduardo Ivanec per provare a vedere se questo era il problema. Quindi il mio codice si è rotto. Ho scoperto che il mio problema era correlato a diversi livelli di ereditarietà, in cui lo strato inferiore era definito sopra il secondo livello inferiore nel modulo.

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''' 

Quando mi sono trasferito MyClass4 sotto MyClass3, è fissato il problema.

Questo è probabilmente un errore da principiante, quindi probabilmente non risolverà la causa del problema originale sopra, ma ho pensato di postare nel caso ci fossero altri rookie là fuori, come me, che stanno facendo lo stesso errore .

(Mi scuso se il mio stile è sbagliato, questo è il mio primo post su Stack Overflow. :))

1

ho avuto lo stesso errore poi ho notato che ho avuto classe duplicato (mio errore) all'interno dello stesso file. py. L'errore è scomparso quando ho rinominato la seconda classe A in 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): 
+0

questo lo ha risolto per me, grazie! – Ghan

Problemi correlati