Saltar al contenido

Patrón Singleton en Python, con ejemplos

En este artículo vamos a describir el patrón singleton en Python que es un patrón que tiene como objetivo garantizar que una clase sólo tenga una instancia.

Herramienta

El patrón singleton es un patrón de creación (Creational Design Pattern) que tiene como objetivo garantizar que una clase sólo tenga una instancia y proporcionar un único punto de acceso a esa instancia. Este patrón suele ser utilizado en temas de logging (entre otros) donde solo queremos tener una instancia del logger que centralice todo.

Existen muchas formas de implementar este patrón; vamos a comentar dos, una sencilla y otra que es interesante comentar por su parecido a Java, las cuales podemos consultar en:  The Singleton — Python 3 Patterns, Recipes and Idioms.

Tal y como se haría en Java

Podemos hacer una implementación similar a la que haríamos en Java, donde lo que estamos haciendo es declarar una clase interna privada (notada por __ ) ya que en python no podemos hacer constructores privados. En esta clase privada tenemos el método de inicialización (__init__), y el método que nos convierte el objeto a string (__str__) para que veamos que está siempre en la misma posición de memoria.

La primera vez que usamos el constructor (__new__) creamos la instancia ya que se cumple la condición de que no tenemos instancia, y, el resto de veces no, simulando los constructores privados en java. También podemos ver que los getters y los setters son accedidos a través de __getattr__ y __setattr__ que llaman a los de la instancia.

# coding=utf-8
class SoyUnico(object):

    class __SoyUnico:
        def __init__(self):
            self.nombre = None

        def __str__(self):
            return `self` + ' ' + self.nombre

    instance = None

    def __new__(cls):
        if not SoyUnico.instance:
            SoyUnico.instance = SoyUnico.__SoyUnico()
        return SoyUnico.instance

    def __getattr__(self, nombre):
        return getattr(self.instance, nombre)

    def __setattr__(self, nombre, valor):
        return setattr(self.instance, nombre, valor)


ricardo = SoyUnico()
ricardo.nombre = "Ricardo Moya"
print(ricardo)
ramon = SoyUnico()
ramon.nombre = "Ramón Invarato"
print(ramon)

print(ricardo)
print(ramon)

Si lo ejecutamos:

<__main__.__SoyUnico instance at 0x7f9f88b24878> Ricardo Moya 
<__main__.__SoyUnico instance at 0x7f9f88b24878> Ramón Invarato 
<__main__.__SoyUnico instance at 0x7f9f88b24878> Ramón Invarato 
<__main__.__SoyUnico instance at 0x7f9f88b24878> Ramón Invarato 

Después de ejecutar el código vemos que lo que tenemos es siempre la variable en la misma posición de memoria (única instancia) y que sólo contiene el último valor porque solo hay una variable.

Forma sencilla

Podemos usar una forma simplificada, donde lo que hacemos la primera vez (usando el constructor nuevamente (__new__)) es instanciar la clase ya que la variable __instance es none y el resto de veces al tener valor, la devolvemos directamente.

# coding=utf-8
class SoyUnico(object):

    __instance = None
    nombre = None

    def __str__(self):
        return `self` + ' ' + self.nombre

    def __new__(cls):
        if SoyUnico.__instance is None:
            SoyUnico.__instance = object.__new__(cls)
        return SoyUnico.__instance

ricardo = SoyUnico()
ricardo.nombre = "Ricardo Moya"
print(ricardo)
ramon = SoyUnico()
ramon.nombre = "Ramón Invarato"
print(ramon)

print(ricardo)
print(ramon)

Ejecutando el código obtenemos:

<__main__.SoyUnico object at 0x7f53d6226050> Ricardo Moya 
<__main__.SoyUnico object at 0x7f53d6226050> Ramón Invarato 
<__main__.SoyUnico object at 0x7f53d6226050> Ramón Invarato 
<__main__.SoyUnico object at 0x7f53d6226050> Ramón Invarato 

«Patrón Singleton en Python, con ejemplos», de Dionisio Cortés en jarroba.com, con licencia Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0. Obra registrada en Safe Creative.

Dionisio Cortés

Ingeniero técnico en informática de sistemas y graduado en ingeniería de software. Unos dirán que soy un javero venido a menos, otros un pythonista venido a más; el caso es que me lo paso bien programando y cacharreando con cualquier lenguaje y tecnología.

Te puede interesar

Patrón Singleton en Java, con ejemplos

El patrón de diseño "Singleton", que en ingeniería del software es un patrón diseñado para limitar la creación de objetos pertenecientes a una clase.

21 Dic 2015

Comentarios (4)

  1. Alejandro

    En el artículo pones «Cómo se haría en Java» creó que debería decir: «Cómo se haría en Python»

    1. calambasm

      Esta haciendo alusión a la forma en que se haría en java, ya se sobre entiende que lo va ha hacer en python.

    2. UPeCer

      Hola, el «como» está escrito sin tilde, por lo tanto no denota una qüestión, sino una afirmación o comparación. (No estoy serguro de si cuando leerías estaba con la tilde jeje). Saludos.

      1. Ramón Invarato Jarroba.com

        Era una comparativa sustituible por «Se programa en Python como se haría en Java».
        Como genera confusión cambio «Como se haría en Java» a «Tal y como se haría en Java».

Deja un comentario


Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.