11 de novembro de 2012

Singleton simples em Python

Sem entrar no mérito de quando usar ou não Singleton, quero apenas mostrar o poder de implementar esse conceito em Python.

Eu já vi algumas implementações diferentes de Singleton em Python, mas até agora a mais simples de todas foi a que o Alex Martelli mostrou em sua palestra The Python Object Model. Vale a pena assistir a essa apresentação.

Segue abaixo:
>>> class Singleton(object):
...     def __new__(cls, *args, **kwargs):
...         if not hasattr(cls, '_instance'):
...             cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
...         return cls._instance
...

Agora, experimente instanciar objetos Singleton:
>>> a = Singleton()
>>> b = Singleton()
>>> a.numero = 1
>>> print a.numero, b.numero
1 1
>>> b.numero += 1
>>> print a.numero, b.numero
2 2 
>>>

Viu? O que se faz no objeto a, reflete no objeto b. Na verdade, os objetos a e b não são iguais. Eles são o mesmo objeto. Em outras palavras, não são gêmeos idênticos. Eles são a mesma pessoa.

Para conferir, dê um print id(a) e print id(b) para ver o mesmo endereço de memória alocada para eles.

Está aí, conforme prometido, um singleton simples em Python

Editado em 13/nov/2012: eu encontrei hoje o post Singleton and Unit Tests, do Felipe Prenholato, que mostra uma implementação de Singleton que pode ser destruído.

Eu sou Vinicius Assef, um programador do século passado que gosta de Python, pratica Lean Development e acredita em Deus. Você pode me contactar por email ou twitter.

5 comentários:

  1. Ótima implementação Vinicius !
    Simples e fácil...

    Ótima dica!

    ResponderExcluir
  2. Bonito exemplo...e errado.

    O método que você tem que implementar pra isso funciona r'e "__new__" e não "__init__" -- O método "__init__" semrpe deve retornar None (isso é, não tem retorno)
    Voce deve ter testado isso com "__new__", e mudou o código antes de postar aqui - por que está chamando o método '__new__' de super

    ResponderExcluir
    Respostas
    1. João, obrigado pela excelente observação.

      Fui no automático e acabei usando __init__() ao invés de __new__(). Já está corrigido.

      Sinta-se à vontade para corrigir qualquer erro que encontrar nesse blog.

      Novamente, muito obrigado.

      Excluir
  3. Olá,

    uma coisa que é legal pensar antes de usar o singleton, é que ele foi é um padrão criado para linguagem que tem apenas OO como paradigma de programação.

    Como Python é multi paradigma é possível ter um resultado semelhante criando uma instância em um módulo, e usar sempre essa instância.

    Valeu!

    ResponderExcluir

Marcadores