Persistência pode ser definida como a manutenção do estado de uma estrutura de dados entre execuções de uma aplicação. A persistência libera o desenvolvedor de escrever código explicitamente para armazenar e recuperar estruturas de dados em arquivos e ajuda a manter o foco na lógica da aplicação.
A forma mais simples e direta de persistência é chamada de serialização e consiste em gravar em disco uma imagem (dump) do objeto, que pode ser recarregada (load) posteriormente. No Python, a serialização é implementada de várias formas, sendo que a mais comum é através do módulo chamado pickle.
Exemplo de serialização:
setup
usando o objeto do arquivo setup.pkl
.setup
default e salva em setup.pkl
.
In [2]:
import pickle
try:
setup = pickle.load(file('setup.pkl'))
print setup
except:
setup = {'timeout': 10,
'server': '10.0.0.1',
'port': 80
}
pickle.dump(setup, file('setup.pkl', 'w'))
Na primeira execução, ele cria o arquivo. Nas posteriores, a saída é a mesma mostrada acima.
Entre os módulos da biblioteca padrão estão disponíveis outros módulos persistência, tais como:
Existem frameworks em Python de terceiros que oferecem formas de persistência com recursos mais avançados, como o ZODB.
Todas essas formas de persistência armazenam dados em formas binárias, que não são diretamente legíveis por seres humanos.
Para armazenar dados em forma de texto, existem módulos para Python para ler e gravar estruturas de dados em formatos:
Zope Object Database (ZODB) é um banco de dados orientado a objeto que oferece uma forma de persistência quase transparente para aplicações escritas em Python e foi projetado para ter pouco impacto no código da aplicação.
ZODB suporta transações, controle de versão de objetos e pode ser conectado a outros backends através do Zope Enterprise Objects (ZEO), permitindo inclusive a criação de aplicações distribuídas em diversas máquinas conectadas por rede.
O ZODB é um componente integrante do Zope, que é um servidor de aplicações desenvolvido em Python, muito usado em Content Management Systems (CMS).
Componentes do ZODB:
Exemplo de uso do ZODB:
In [1]:
from ZODB import FileStorage, DB
import transaction
# Definindo o armazenamento do banco
storage = FileStorage.FileStorage('people.fs')
db = DB(storage)
# Conectando
conn = db.open()
# Referência para a raiz da árvore
root = conn.root()
# Um registro persistente
root['singer'] = 'Kate Bush'
# Efetuando a alteração
transaction.commit()
print root['singer'] # Kate Bush
# Mudando um item
root['singer'] = 'Tori Amos'
print root['singer'] # Tori Amos
# Abortando...
transaction.abort()
# O item voltou ao que era antes da transação
print root['singer'] # Kate Bush
O ZODB tem algumas limitações que devem ser levadas em conta durante o projeto da aplicação:
Objetos “serializáveis” são aqueles objetos que podem ser convertidos e recuperados pelo Pickle. Entres os objetos que não podem ser processados pelo Pickle, estão aqueles implementados em módulos escritos em C, por exemplo.
YAML é um formato de serialização de dados para texto que representa os dados como combinações de listas, dicionários e valores escalares. Tem como principal característica ser legível por humanos.
O projeto do YAML foi muito influenciado pela sintaxe do Python e outras linguagens dinâmicas. Entre outras estruturas, a especificação do YAML define que:
Listas podem ser representadas assim:
- Azul
- Branco
- Vermelho
Ou
[azul, branco, vermelho]
Dicionários são representados como:
cor: Branco
nome: Bandit
raca: Labrador
PyYAML é um módulo de rotinas para gerar e processar YAML no Python.
Exemplo de conversão para YAML:
In [2]:
import yaml
progs = {'Inglaterra':
{'Yes': ['Close To The Edge', 'Fragile'],
'Genesis': ['Foxtrot', 'The Nursery Crime'],
'King Crimson': ['Red', 'Discipline']},
'Alemanha':
{'Kraftwerk': ['Radioactivity', 'Trans Europe Express']}
}
print yaml.dump(progs)
Exemplo de leitura de YAML. Arquivo de entrada prefs.yaml
:
- musica: rock
- cachorro:
cor: Branco
nome: Bandit
raca: Labrador
- outros:
instrumento: baixo
linguagem: [python, ruby]
comida: carne
Código em Python:
In [3]:
import pprint
import yaml
# yaml.load() pode receber um arquivo aberto
# como argumento
yml = yaml.load(file('prefs.yaml'))
# pprint.pprint() mostra a estrutura de dados
# de uma forma mais organizada do que
# o print convencional
pprint.pprint(yml)
YAML é muito prático para ser usado em arquivos de configuração e outros casos onde os dados podem ser manipulados diretamente por pessoas.
A partir versão 2.6, foi incorporado a biblioteca do Python um módulo de suporte ao JSON (JavaScript Object Notation). O formato apresenta muitas similaridades com o YAML e tem o mesmo propósito.
Exemplo:
In [4]:
import json
desktop = {'arquitetura': 'pc', 'cpus': 2, 'hds': [520, 270]}
print json.dumps(desktop)
O JSON usa a sintaxe do JavaScript para representar os dados e é suportado em várias linguagens.
In [1]:
Out[1]: