I find myself practicing with Python , doing a little POO , a class here, another over there ... :) ... and, also, with handling of files and pickle .
I expose the code block of a file called "manager.py":
# encoding: utf-8
from io import open
import pickle
class Categoria:
def __init__(self, nombre):
self._id = 0
self.nombre = nombre
def __str__(self):
return '\t-> [{}] - {}.'.format( self._id, self.nombre.upper() )
class Gestor_Categorias:
categorias = []
id_nuevo = 0
def __init__(self):
self.cargar()
'''
Recogiendo el ID del último registro insertado
'''
def dame_id_nuevo(self):
if len(self.categorias) == 0:
self.id_nuevo += 1
else:
cat_ultimo_registro = self.categorias[-1]
self.id_nuevo = int(cat_ultimo_registro._id) + 1
return self.id_nuevo
def agregar(self, cat):
existe = self.buscar_si_existe(cat.nombre)
if existe[0] == False:
#Pasar el nuevo ID
cat._id = self.dame_id_nuevo()
self.categorias.append(cat)
self.guardar()
def buscar_si_existe(self, nombre):
existe = False
cat_bucle = ''
for cat_bucle in self.categorias:
if( cat_bucle.nombre == nombre ):
existe = True
cat_bucle = cat_bucle
return [existe, cat_bucle]
def mostrar(self):
if len(self.categorias) == 0:
print("\t-> El Gestor de CATEGORÍAS está vacío.")
return
print('')
for cat in self.categorias:
print '\t',
print(cat)
def cargar(self):
fichero = open('gestor_categorias.pckl', 'ab+')
#Como el comando anterior de APPEND pone el puntero al final,
#habrá que recolocarlo al inicio del fichero
fichero.seek(0)
try:
#en la primera carga, al estar vacío,
#saltará hasta la excepción
self.categorias = pickle.load(fichero)
except:
print("Creación satisfactoria del fichero de CATEGORÍAS ... ¡¡OK!!")
finally:
fichero.close()
if( len(self.categorias) == 1 ):
print("\nSe ha cargado {} categoría.".format( len(self.categorias) ))
else:
print("\nSe han cargado {} categorías.".format( len(self.categorias) ))
def guardar(self):
fichero = open('gestor_categorias.pckl', 'wb')
pickle.dump(self.categorias, fichero)
fichero.close()
def borrar(self, nombre):
#Borrado total o único :: ini
#---------------------------------------------------
if( nombre.lower() == 'total' ):
tot = len(self.categorias)
for cat in self.categorias:
self.categorias.remove( cat )
self.guardar()
print("""
Se borraron todas las categorías ({} en total).
-> El archivo quedó vacío.
""".format( tot ))
else:
existe = self.buscar_si_existe(nombre)
if existe[0]:
self.categorias.remove( existe[1] )
self.guardar()
print( '\nLa categoría llamada "{}" fue borrada.'.format( nombre ) )
#return
#---------------------------------------------------
#Borrado total o único :: fin
# Destructor de clase
def __del__(self):
self.guardar() # guardado automático
print("\n:: Se ha guardado el fichero de CATEGORÍAS - FIN ::")
#Acciones de Ejecución
#==========================================================
#[ CATEGORÍAS ]
''''''
gC = Gestor_Categorias()
gC.mostrar()
gC.agregar( Categoria('Arqueros') )
When executing this code, after creating the file if it does not already exist, the following exception is sent, I think, to the method " __ of __ " of the class " Gestor_Categorias ":
Exception AttributeError: "'NoneType' object has no attribute 'dump'" in <bound method Gestor_Categorias.__del__ of <__main__.Gestor_Categorias instance at 0x7f82dc406f38>> ignored
In the method " __ of __ " of the class " Gestor_Categorias ", I call the method of "save ()" to make a save of the file changes when closing the program.
As a curiosity, I have another file traced to it with two other classes (Character and Gestor_Personals) that also saves the records in the same way in a file and when closing (with its "__del__") it calls its "save () "but this exception is not thrown.
I have seen some other post about similar exceptions but I do not get to solve it with the recommendations that I have read.
So, can someone help me understand why the exception is thrown? How to solve it? Is it necessary not to implement the __del__ method? and, if it can not be implemented, where could I make the last call to "save ()" that I have on __del__ before closing?
Thanks for the possible answers.