El comportamiento de Python super () no es confiable

Por alguna razón, el método super() no siempre se comporta como se espera, optando por regresar:

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

Entiendo lo que significa el error. No entiendo por qué viene como un error. Aquí está el fragmento de código que se está rompiendo. Todos los objetos en el sistema son nuevos objetos de estilo.

Lo que es realmente interesante es que este error no siempre aparece. No sé qué lo está causando. El método super() en Retrieval pasa la clase Retrieval y luego a sí mismo como un objeto, que es, por lo que yo sé, exactamente cómo se supone que se invoca super() .

¿Algún pensamiento en absoluto?

En el archivo DBConnection.py :

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

En el archivo de recuperación.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 

¿Estás recargando módulos de alguna manera en medio de las cosas? Si es así, eso puede explicar este error.

isinstance(self,DBAdminConnection) puede volverse falso después de volver a cargar los módulos debido a los cambios en las referencias de memoria, al parecer.

Editar: si está ejecutando su aplicación web.py bajo mod_wsgi, asegúrese de que está deshabilitando la carga automática:

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

Si está utilizando reload () como parte de su flujo de trabajo, aparentemente también necesita usar super(self.__class__, self).__init__ para la inicialización de la herencia.

Sospecho que encontrará que este error coincide con el error de id(self.__class__) ==id(Retrieval) .

No estoy seguro de por qué está ocurriendo el error, pero como ayuda para la depuración, podría ajustar la llamada a super en un bloque try/except y hacer un volcado de datos cuando se produce la excepción. Algo como esto:

 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 

Acabo de tener el mismo problema, ejecutando mi código en el cuaderno de Jupyter. Estaba usando reload, así que reinicié mi kernel para hacer un seguimiento de la respuesta de Eduardo Ivanec para probar y ver si este era el problema. Entonces mi código se rompió. Descubrí que mi problema estaba relacionado con varias capas de herencia, donde la capa inferior se definía sobre la segunda capa inferior en el módulo.

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

Cuando moví MyClass4 debajo de MyClass3, solucionó el problema.

Este es probablemente un error de novato, así que probablemente no resuelva la causa del problema original anterior, pero pensé que publicaría en caso de que haya otros novatos, como yo, que cometan el mismo error.

(Disculpas si mi estilo es incorrecto, esta es mi primera publicación en Stack Overflow. :))

Tuve el mismo error y luego me di cuenta de que tenía una clase duplicada (mi error) dentro del mismo archivo.py. El error desapareció cuando cambié el nombre de la segunda clase A a la clase 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):