Persistência em Python, criando uma agenda simples
Persistê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:

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 é?
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 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.

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.


about 2 years ago
muito bom
fiz um programa de controle de estoque em PyGTK que também usa o shelve, o lojinha:
http://www.gnutopia.net/lucas/lojinha_06.deb
esse pacote é .deb , ou seja , so presta em distros baseadas no debian (que tem o apt)
about 2 years ago
Depois eu faço uma versão dessa agenda usando o PyGTK ou o PyQt.
about 2 years ago
Interessante! Também vi suas tirinhas, gostei especialmente do Orc matador, ehuaehuaehaeuhaeu!!!
about 2 years ago
É o Plugin Live Preview Textile.
Peguei as instruções nesse blog:
http://donodavoz.com/live-preview-textile/
about 2 years ago
o módulo shelve tem foco na facilidade e não no desempenho
about 2 years ago
Python vai fazer eu concluir algo que venho enrolando faz tempo, aprender a programar de verdade. Fazem anos que eu brinco de programar mas nunca aprendi uma linguagem a fundo mas a facilidade e poder dessa linguagem estão me convencendo a comprar uns livros e mergulhar de cabeça.
about 2 years ago
Muito bom o artigo. Explicação detalhada e exemplos bem colocados. Fazia tempo que eu queria mexer com persistência e sua explicação me deu vontade de testar.
Parabéns!
Marco André
about 2 years ago
Muito massa!!!
Que plugin você usa para colorir os fontes?
about 2 years ago
WP-Syntax, o único que funcionou comigo:
http://wordpress.org/extend/plugins/wp-syntax/
O problema é que ele tem uns 300Kb, porque ele leva o Geshi dentro dele.
about 2 years ago
Pow achei a agenda legal.
coloquei tudo que você utilizou mas quando dei um run. a lista não foi mostrada…
mas ficou show
about 2 years ago
Sem palavras! Continue escrevendo sobre python, indique links etc…
about 2 years ago
Alguém conhece uma agenda em python que salve os dados no padrão vcard e possa rodar graficamente no windows e no linux? qualquer resposta pode ser enviada para voyeg3r no Gmail.
Grato!
about 2 years ago
Olá, bem interessante o shelve… o python encanta por essas funcionalidades simples e prontas… você sabe dizer se existe algo semelhante ao shelve só que para o Java?
vlw, abraços.
about 1 year ago
Olá, tudo bem…estou inciando no Python, mais estou realizando meus estudos e teste no windows disgitei todos os passo, não deu erro porém não consigo fazer nada…como devo proceder estou utilizando o python versão 2.5.2.
desde ja agradeço,
Rodrigo Rodrigues
about 1 year ago
Rodrigo, você está conseguindo acessar o console Python? Você consegue rodar seus próprios programas?
Para quem está aprendendo com Python e também para quem já conhece um pouco, eu recomendo esse livro aqui, que é todo de graça:
http://www.diveintopython.org/toc/index.html
about 1 year ago
Obrigado mesmo Silveira pela dica..
um abraço
about 1 year ago
Silveira,
Muito legal este código, realmente fascinante… porém,
redigi o seu codigo exatamente da forma como você postou e o mesmo não me retornou nada. oque pode ter ocorrido?