¿Cómo borrar datos de instancia sin setattr?
Frecuentes
Visto 155 veces
1
Quería hacer una clase transitable (por base de datos, archivo único o simplemente como cadena) en python. Escribo esto (abreviado):
from json import JSONDecoder, JSONEncoder
def json_decode(object): return JSONDecoder().decode(object)
def json_encode(object): return JSONEncoder().encode(object)
class Storage:
__separator__ = 'ANY OF ANYS'
__keys__ = []
__vals__ = []
__slots__ = ('__keys__', '__vals__', '__separator__')
def __getattr__(self, key):
try:
return self.__vals__[self.__keys__.index(key)]
except IndexError:
raise AttributeError
def __setattr__(self, key, val):
self.__keys__.append(key)
self.__vals__.append(val)
def store(self):
return (json_encode(self.__keys__) + self.__separator__ +
json_encode(self.__vals__))
def restore(self, stored):
stored = stored.split(self.__separator__)
for (key, val) in zip(json_decode(stored[0]), json_decode(stored[1])):
setattr(self, key, val)
Y sí, eso funciona, pero... Cuando hago más instancias, todas son como singleton.
Entonces, cómo establecer el atributo a la instancia sin _setattr_?
PD. Tengo una idea - hacer en establecer/getattr un pase para claves/valores, pero hará un lío.
2 Respuestas
0
tu __separator__
, __keys__
, __vals__
y __slots__
son atributos del objeto "Almacenamiento" (objeto de clase). No sé si es exactamente lo mismo, pero lo llamaría variables estáticas de la clase.
Si desea tener valores diferentes para cada instancia de Almacenamiento, defina cada una de estas variables en su __init__
función:
class Storage(object):
__slots__ = ('__keys__', '__vals__', '__separator__')
def __init__(self):
super(Storage, self).__setattr__('__separator__', "ANY OF ANYS")
super(Storage, self).__setattr__('__keys__', [])
super(Storage, self).__setattr__('__vals__', [])
def __getattr__(self, key):
try:
vals = getattr(self, '__vals__')
keys = getattr(self, '__keys__')
return vals[keys.index(key)]
except IndexError:
raise AttributeError
def __setattr__(self, key, val):
vals = getattr(self, '__vals__')
keys = getattr(self, '__keys__')
vals.append(val)
keys.append(key)
editado para que getattr y setattr funcionen
Tengo ese problema hace 2 días. No sé si ese es exactamente tu problema, pero dijiste que "es como si tuviera un singleton".
Respondido el 12 de junio de 12 a las 22:06
0
Podrías hacer tu Storage
clase una subclase de una clase base especial como esta:
class Singleton(object):
def __new__(cls, *args, **kwargs):
if '_inst_' not in vars(cls):
cls._inst = type.__new__(cls, *args, *kwargs)
return cls._inst
class Storage(Singleton):
....
Siempre y cuando no anules __new__()
en su subclase, todas las llamadas posteriores para crear nuevas instancias después de la primera devolverán la que se creó primero.
Respondido el 12 de junio de 12 a las 22:06
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas python json class or haz tu propia pregunta.
ranuras son para guardar memoria (google it) self.xxx será analizado por setattr, así que eso no es lo que quiero. - Radoslaw Miernik
entonces vete
__slots__
como era antes. Pero si no establece un diferente[]
a ambos__keys__
y__vals__
en cada instancia (como sugerí), compartirá la misma lista en todas sus instancias: Alberto FerrasLo intenté.
__getattr__
. Cuando quieroself.__key/vals__
, obtuve un error profundo de recurrencia máxima -__getattr__
operar en__key/vals__
. - Radoslaw Miernikeso fue porque en
__init__
estaba usando tu nuevo obtener función, actualicé el código (y probé, funciona para mí con múltiples instancias). Es un poco complicado pero hace el trabajo. - Alberto Ferrasahora entiendo tu problema :) Si no es lo que querías (porque uso el objeto de clase para heredar el obtener) entonces está bien, esperaré aquí para ver la solución - Alberto Ferras