Única instancia de clase en Python

Estoy creando una aplicación Python que incluye comunicación de socket con un servidor. Me gustaría tener un módulo que pueda usarse en toda mi aplicación (varios otros módulos). Actualmente mi módulo se ve así:

class SocketCommunication: def __init__(self): self.socketIO = SocketIO(settings.ADDRESS, settings.PORT, Namespace) def emit(self, message, data): json_data = json.dumps(data.__dict__) self.socketIO.emit(message, json_data) class Namespace(BaseNamespace): def on_connect(self): print '[Connected]' def on_disconnect(self): print "[Disconnected]" 

Cuando uso esto en otros módulos hago lo siguiente:

 import SocketCommunication self.sc = SocketCommunication() 

El problema es que cada vez que hago esto, se crea una nueva conexión que se mostrará como un nuevo cliente en el servidor, y eso es indeseable. Por lo que puedo leer, debe evitarse Singletons en Python y, por lo tanto, tengo curiosidad acerca de qué es la mejor práctica para este tipo de problema.

Las siguientes son tres formas de usar singleton en Python. Usando metaclass y decorator para alcanzar la meta.

  1. usar __new__

     class Singleton(object): def __new__(cls, *args, **kw): if not hasattr(cls, '_instance'): orig = super(Singleton, cls) cls._instance = orig.__new__(cls, *args, **kw) return cls._instance class MyClass(Singleton): a = 1 one = MyClass() two = MyClass() two.a = 3 print one.a #3 print id(one) #29097904 print id(two) #29097904 print one == two #True print one is two #True 
  2. utilizar __metaclass__

     class Singleton2(type): def __init__(cls, name, bases, dict): super(Singleton2, cls).__init__(name, bases, dict) cls._instance = None def __call__(cls, *args, **kw): if cls._instance is None: cls._instance = super(Singleton2, cls).__call__(*args, **kw) return cls._instance class MyClass2(object): __metaclass__ = Singleton2 one = MyClass2() two = MyClass2() two.a = 3 print one.a #3 print id(one) #31495472 print id(two) #31495472 print one == two #True print one is two #True 
  3. usar decorator

      def singleton(cls, *args, **kw): instances = {} def _singleton(): if cls not in instances: instances[cls] = cls(*args, **kw) return instances[cls] return _singleton @singleton class MyClass3(object): a = 1 def __init__(self, x=0): self.x = x one = MyClass3() two = MyClass3() two.a = 3 print one.a #3 print id(one) #29660784 print id(two) #29660784 print one == two #True print one is two #True one.x = 1 print one.x #1 print two.x #1 

Prefiero usar decorator .

Los Singletons son controvertidos porque a menudo se usan como una forma de envolver las variables globales. Es por esto que algunas personas abogan por su evitación. Los indicadores globales hacen que las pruebas sean más difíciles, limitan el control de acceso y, a menudo, conducen a un fuerte acoplamiento entre variables. (consulte http://wiki.c2.com/?GlobalVariablesAreBad para obtener más detalles sobre por qué los globales son generalmente una mala práctica)

En su caso particular, es probable que sea apropiado usar un singleton porque simplemente está tratando de impedir que SocketCommunication se inicialice varias veces (por una buena razón), en lugar de intentar usarlo como un contenedor para un estado global.

Ver Son Singletons realmente tan malo? ¿ Y qué hay de malo en los singletons? para un poco de discusión sobre Singletons.