Se entiende mejor con un ejemplo sencillo (PYTHON 2.7) :
class A:
# _instance es un atributo que conoce el Singleton
_instance = None
def foo(self):
return id(self)
def Singleton(cls):
# cls identifica la clase que solo debe instanciarse una vez por proceso
if not cls._instance:
print 'primera instancia del Singleton'
cls._instance = cls()
return cls._instance
# subclase A
class B(A):
pass
b = Singleton(A)
c = Singleton(B)
d = Singleton(A)
print id(b),b.foo()
print id(c),c.foo()
print id(d),d.foo()
En este caso deseamos que la clase A se instancie una sola vez y esa instancia se comparta entre todos los procesos que la instanciarán posteriormente. Al instanciar la clase A con b=Singleton(A) creamos una primera instancia que se compartirá con las siguientes inicialización de la clase : c= Singleton(B) y d=Singleton(A).
Posteriormente comprobamos el id de cada clase, siendo el mismo identificador :
primera instancia del singleton
32730128 32730128
32730128 32730128
32730128 32730128
A continuación crearemos otro ejemplo sobreescribiendo el método __new__ de una clase, convirtiéndola en Singleton :
class A(object):
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super(A, cls).__new__(cls, *args, **kwargs)
return cls._instance
if __name__ == '__main__':
b = A()
c = A()
if (id(b) == id(c)):
print "Igual instancia"
else:
print "Diferente instancia"
En este caso, comprueba que también existe _instance como una variable de clase, igual que en ejemplo anterior, que almacena la instancia de clase. _instance se inicializa con la primera instancia de clase y devolverá el mismo valor de instancia a cada inicialización de clase que realizan los posteriores procesos.
A continuación mostramos otro ejemplo Singletón con decorador :
def singleton(cls):
obj = cls()
# Siempre devuelve el mismo objeto
cls.__new__ = staticmethod(lambda cls: obj)
# Desabilita __init__
try:
del cls.__init__
except AttributeError:
pass
return cls
@singleton
class A(object):
pass
if A() is A():
print "Es lo mismo!"
else:
print "Es diferente!"
Hasta aquí he querido poner algo de luz sobre el patrón SINGLETON.
No hay comentarios:
Publicar un comentario