Prateleira ShelvePersistência, em programação, é guarda alguma informação para você pegar depois.

A solução mais comum para persistência de dados são os bancos de dados, que podem resolver esse problema de uma maneira sofisticada e eficiente.

Por outro lado, para usar um banco de dados você vai precisar:

  • Instalar um banco de dados
  • Aprender a linguagem de consulta do banco de dados, geralmente SQL.
  • Fazer a ligação do banco de dados com a linguagem que você está usando.

Tudo isso é chato e complicado, ainda mais se você quer fazer algo bem simples onde o desempenho não é um fator crítico. Você também poderia guardar suas informações num arquivo mas você teria que tratar vários aspectos de baixo nível.

Python tem algumas maneiras simples e fáceis de tratar persistência. Uma delas é o Shelve, que é um módulo padrão do Python.

Para brincar com ele abra seu terminal python digitando python no seu console:

>>> import shelve
>>> arq = shelve.open(‘asdf’)
>>> arq['site'] = ‘http://www.python.org’
>>> arq['pi'] = 3.1415
>>> arq['fibo'] = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
>>> print arq['pi']
3.1415
>>> print arq['fibo']
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
>>> del arq['site']

import shelve vai importa o módulo shelve. arq vai receber o arquivo asdf, que se não existir vai ser criado. Depois disso você pode usar arq como um dicionário comum, indexado por uma string chave. Para deletar alguem do arquivo simplesmente dê um del arq[chave].

Experimente fechar seu console e olhar como ficou o diretório onde você executou o terminal Python:

Gnome: olhando como ficou o diretório

Um arquivo asdf foi criado. Você não precisa se preocupar como esses dados estão guardados dentro desse arquivo, o shelve vai cuidar disso para você.

Agora se você abrir novamente o console dentro desse diretório:

>>> import shelve
>>> arq = shelve.open(‘asdf’)
>>> for chave in arq:
… print chave, arq[chave]

fibo [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
pi 3.1415

Tadã! Seus dados de volta.

Fica bem mais fácil fazer programas com persistência agora não é?

Livros Python Vá mais longe! Livros de Como Programar em Python pelos menores preços.

Buscapé.

Por exemplo, vamos fazer uma agenda telefônica bem simples:

Diagrama de caso de uso de uma agenda telefônica bem simples
Diagrama UML de Caso de Uso para uma agenda bem simples

Para cada bolinha dessas (caso de uso) nós fazemos uma função que desempenha essa ação. São 4 bolinhas, então 5 funções:

# Ver agenda toda
def mostra_todos_registros(agenda):
   for nome in agenda:
      print nome, agenda[nome]

# insere alguem
def insere(agenda, nome, telefone):
   agenda[nome] = telefone

# mostra um determinado nome da agenda
def busca(agenda, nome):
   try:
      print nome, agenda[nome]
   except Exception:
      print nome, 'não está na agenda.'

# apaga alguém
def apaga(agenda, nome):
   try:
      del agenda[nome]
   except Exception:
      print nome, 'não está na agenda.'

# apaga todos os nomes da agenda
def limpa(agenda):
   for nome in agenda:
      del agenda[nome]

# ajuda para --help
def ajuda():
   print "Uso:"
   print sys.argv[0], "[comandos] [parâmetros]"
   print "t--help: mostra esta ajuda"
   print "t--show NOME: mostra o NOME e seu respectivo telefone"
   print "t--show: mostra todos os nomes. É a operacao padrao"
   print "t--add NOME TELEFONE: adiciona NOME e TELEFONE para a agenda"
   print "t--del NOME: remove NOME e seu respectivo telefone da agenda"
   print "t--clean: apaga todos os nomes da agenda."

Adicionamos uma função a mais, ajuda, para que mostra uma instrução de uso para o usuário quando ele errar algum comando ou quando pedir ajuda.

Nossa agenda (agenda.py) vai funcionar da seguinte forma:

  • agenda.py add Silveira 123-4567: adiciona o nome Silveira na agenda com o telefone 123-4567.
  • agenda.py show: mostra todo mundo da agenda.
  • agenda.py del Silveira: deleta Silveira da agenda, se existir.
  • agenda.py clean: apaga todo mundo da agenda.

Ou seja, tudo pela linha de comando, bem simples. Os argumentos da linha de comando no python ficam no vetor argv do módulo sys.

O tratamento da linha de comando é um pouco chato, mas não é muito complicado nesse caso:

def main():
   # se nao for passado nenhum comando, o comando eh para mostrar tudo
   if len(sys.argv) == 1:
      comando = "show"
   else:
      comando = sys.argv[1]
   comando.lower()

   # abre a agenda
   agenda = shelve.open('agenda.db')

   # Help
   if comando in ("help", "-h", "--help", "ajuda"):
      ajuda()
   # visualização
   elif comando in ("show", "-s", "--show"):
      if len(sys.argv) == 1 or len(sys.argv) == 2:
         mostra_todos_registros(agenda)
      elif len(sys.argv) == 3:
         nome = sys.argv[2]
         busca(agenda, nome)
      else:
         ajuda()
   # deleção
   elif comando in ("del", "-d", "-del", "--del", "delete"):
      if len(sys.argv) == 3:
         nome = sys.argv[2]
         apaga(agenda, nome)
      else:
         ajuda(bin)
   # inserção
   elif comando in ("add", "-a", "-add", "--add"):
      if len(sys.argv) == 4:
         nome = sys.argv[2]
         tel = sys.argv[3]
         insere(agenda, nome, tel)
      else:
         ajuda()
   # destruição
   elif comando in ("clean", "-c", "-clean", "--clean"):
      limpa(agenda)
   else:
      ajuda()

   # fecha o banco
   agenda.close()

Adicionando as importações, alguns comentários e detalhes ficamos com o código completo abaixo:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
Uma agenda bem simples. Digite --help para obter ajuda.
visite http://www.eupodiatamatando.com para maiores informações.
"""

import shelve
import sys

# Ver agenda toda
def mostra_todos_registros(agenda):
   for nome in agenda:
      print nome, agenda[nome]

# insere alguem
def insere(agenda, nome, telefone):
   agenda[nome] = telefone

# mostra um determinado nome da agenda
def busca(agenda, nome):
   try:
      print nome, agenda[nome]
   except Exception:
      print nome, 'não está na agenda.'

# apaga alguém
def apaga(agenda, nome):
   try:
      del agenda[nome]
   except Exception:
      print nome, 'não está na agenda.'

# apaga todos os nomes da agenda
def limpa(agenda):
   for nome in agenda:
      del agenda[nome]

# ajuda para --help
def ajuda():
   print "Uso:"
   print sys.argv[0], "[comandos] [parâmetros]"
   print "t--help: mostra esta ajuda"
   print "t--show NOME: mostra o NOME e seu respectivo telefone"
   print "t--show: mostra todos os nomes. É a operacao padrao"
   print "t--add NOME TELEFONE: adiciona NOME e TELEFONE para a agenda"
   print "t--del NOME: remove NOME e seu respectivo telefone da agenda"
   print "t--clean: apaga todos os nomes da agenda."

def main():
   # se nao for passado nenhum comando, o comando eh para mostrar tudo
   if len(sys.argv) == 1:
      comando = "show"
   else:
      comando = sys.argv[1]
   comando.lower()

   # abre a agenda
   agenda = shelve.open('agenda.db')

   # Help
   if comando in ("help", "-h", "--help", "ajuda"):
      ajuda()
   # visualização
   elif comando in ("show", "-s", "--show"):
      if len(sys.argv) == 1 or len(sys.argv) == 2:
         mostra_todos_registros(agenda)
      elif len(sys.argv) == 3:
         nome = sys.argv[2]
         busca(agenda, nome)
      else:
         ajuda()
   # deleção
   elif comando in ("del", "-d", "-del", "--del", "delete"):
      if len(sys.argv) == 3:
         nome = sys.argv[2]
         apaga(agenda, nome)
      else:
         ajuda(bin)
   # inserção
   elif comando in ("add", "-a", "-add", "--add"):
      if len(sys.argv) == 4:
         nome = sys.argv[2]
         tel = sys.argv[3]
         insere(agenda, nome, tel)
      else:
         ajuda()
   # destruição
   elif comando in ("clean", "-c", "-clean", "--clean"):
      limpa(agenda)
   else:
      ajuda()

   # fecha o banco
   agenda.close()

if __name__ == "__main__":
   main()

Voilá! Temos uma agenda bem simples, mas funcional.

Captura de tela da nossa agendinha

Vale  resaltar que o módulo shelve tem foco na facilidade e não no desempenho. Para aplicações maiores eu sugiro você procurar o módulo específico de um banco de dados mais robusto.