[Python-es] clases singleton, herededas de thread, que se instancian a su vez desde otros hilos...

Oswaldo listas en soft-com.es
Mie Jun 1 11:49:22 CEST 2011


El 01/06/2011 1:56, Jose Caballero escribió:
> Hola,
>

 > D. ¿Cuál es la forma más sencilla de implementar los 'singleton' en
 > python? He visto mil y una soluciones en google, lo que me hace pensar
 > que no existe una forma verdadera. Me conformo con la más sencilla... ;)
 >

Hay multiples formas de implementarlo, personalmente utilizo la 
implementacion singleton como metaclase:

class Singleton(type):
     # http://es.wikipedia.org/wiki/Singleton#Python
     def __init__(cls, name, bases, dct):
         cls.__instance = None
         type.__init__(cls, name, bases, dct)

     def __call__(cls, *args, **kw):
         if cls.__instance is None:
             cls.__instance = type.__call__(cls, *args,**kw)
         return cls.__instance

class miclasesingleton(object):
     __metaclass__ = Singleton
     def __init__(.....


 > A. ¿Es necesario que C1 sea 'singleton', o solo deberían serlo H1...Hn?
 > ¿O da igual?
 > B. ¿Es mejor que C1 herede de threading.Threading o sería mejor que lo
 > hagan H1...Hn? ¿O da igual?

Por simplicidad:

class C1(treading.Thread):
     __metaclass__ = Singleton

Todas las clases derivadas de C1 son Threads y singleton


 > C. El hecho de que los objetos de C2 y de H1...Hn se instancien desde
 > objetos que son a su vez hilos, ¿puede hacer que las clases C2 y 
H1...Hn dejen de ser realmente 'singletons'?

No


 > class C3(threading.Thread):
 >          def __init__ ... bla bla
 >          def run(self):
 >                  obj_H1 = H1()
 >                  obj_H1.start()
 >                  ...
 >                  obj_Hn = Hn()
 >                  obj_Hn.start()
 >
 >                  obj_C2 = C2()
 >                  obj_C2.start()
 >                  # bla bla
 >          # bla bla
 >
 > obj_C3_1 = C3()
 > obj_C3_1.start()
 > ...
 > obj_C3_j = C3()
 > obj_C3_j.start()

Aqui tienes un problema:

Cuando realices:
     obj_C3_1 = C3()
     obj_C3_1.start()

se crearan las instancias iniciales de las clases H1..Hn (singletons)

Cuando a continuación realices:
     obj_C3_j = C3()
     obj_C3_j.start()

En metodo run() intentrá crear nuevas instancias de H1..Hn, pero como 
son singletons utilizará las mismas que ya creastes y activastes en 
obj_C3_1 y dará error.


Esta todo un poco lioso, haz pruebas con objetos simples.

Saludos,


-- 
Oswaldo Hernández


Más información sobre la lista de distribución Python-es