Una referencia fuerte de AKA normal es aquella que mantiene vivo el objeto referido: en CPython, cada objeto mantiene el número de referencias (normales) que existen (conocido como "recuento de referencia" o RC) y se va tan pronto como el RC llegue a cero (la marca generacional ocasional y los pases de barrido también recogen "bucles de referencia" de vez en cuando).
Cuando no quiere que un objeto permanezca vivo simplemente porque otro se refiere a él, entonces utiliza una "referencia débil", una variedad especial de referencia que no incrementa el RC; ver the docs para más detalles. Por supuesto, dado que el objeto referido PUEDE desaparecer si no se lo menciona (¡el propósito del ref débil en vez de uno normal!), El objeto de referencia debe ser advertido si trata de usar un objeto eso se ha ido, y esa alerta se da exactamente por la excepción que estás viendo.
En su código ...:
def __init__(self,dbname):
tmp = sqlite.connect(dbname)
self.con = tmp.cursor()
def __del__(self):
self.con.close()
tmp
es una referencia normal a la conexión ... pero es una variable local, por lo que desaparece al final de __init__
. El (curiosamente llamado ;-) cursor self.con
permanece, PERO está implementado internamente para mantener solo una referencia DÉBIL a la conexión, por lo que la conexión desaparece cuando lo hace tmp
. Por lo tanto, en __del__
falla la llamada al .close
(ya que el cursor necesita usar la conexión para cerrarse).
solución más simple es el siguiente pequeño cambio:
def __init__(self,dbname):
self.con = sqlite.connect(dbname)
self.cur = self.con.cursor()
def __del__(self):
self.cur.close()
self.con.close()
También he tenido la oportunidad de utilizar con la conexión y act de cursor, pero Python no le importará si está dispuesta a intercambiar los (Dejarás perplejos a los lectores ;-).
El problema es que no sé qué significa "débil" o "fuerte". Ni siquiera sé lo que significa la referencia. – Verrtex