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 é: {'port': 80, 'timeout': 10, 'server': '10.0.0.1'} Entre os módulos da biblioteca padrão estão disponíveis outros módulos persistência, tais como: ▪ cPickle: versão mais eficiente de pickle, porém não pode ter subclasses. ▪ shelve: fornece uma classe de objetos persistentes similares ao dicionário. 28 Em inglês, serialization ou marshalling. 132 Persistência 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 de forma de texto, existem módulos para Python para ler e gravar estruturas de dados em formatos: ▪ JSON29 (JavaScript Object Notation). ▪ YAML30 (YAML Ain't a Markup Language). ▪ XML31 (Extensible Markup Language). 29 Página do formato em: http://www.json.org/. 30 Página do formato em: http://yaml.org/. 31 Página do formato em: http://www.w3.org/XML/. Persistência 133 ZODB 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 Zope32, que é um servidor de aplicações desenvolvido em Python, muito usado em Content Management Systems (CMS). Componentes do ZODB: ▪ Database: permite que a aplicação abra conexões (interfaces para acesso aos objetos). ▪ Transaction: interface que permite tornar as alterações permanentes. ▪ Persistence : fornece a classe base Persistent. ▪ Storage: gerencia a representação persistente em disco. ▪ ZEO: compartilhamento de objeto entre diferentes processos e máquinas. 32 Documentação e pacotes de instalação do Zope e produtos ligados a ele em http://www.zope.org/. Aplicação persistente ZODB ZODB: Zope Object Database Database TransactionPersistence StorageZEO 134 Persistência Exemplo de uso do ZODB: # -*- coding: latin1 -*- 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 raíz 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 atributo root['singer'] = 'Tori Amos' print root['singer'] # Tori Amos # Abortando... transaction.abort() print root['singer'] # Kate Bush O ZODB tem algumas limitações que devem ser levadas em conta durante o projeto da aplicação: ▪ Os objetos precisam ser “serializáveis” para serem armazenados. ▪ Objetos mutáveis requerem cuidados especiais. 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 os objetos implementados em módulos escritos em C, por exemplo. Persistência 135 YAML 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ção33 do YAML define que: ▪ Os blocos são marcados por endentação. ▪ Listas são delimitadas por colchetes ou indicadas por traço. ▪ Chaves de dicionário são seguidas de dois pontos. Listas podem ser representadas assim: - Azul - Branco - Vermelho Ou: [azul, branco, vermelho] Dicionários são representados como: cor: Branco nome: Bandit raca: Labrador PyYAML34 é uma biblioteca de rotinas para gerar e processar YAML no Python. Exemplo de conversão para YAML: import yaml progs = {'Inglaterra': {'Yes': ['Close To The Edge', 'Fragile'], 'Genesis': ['Foxtrot', 'The Nursery Crime'], 33 Disponível em: http://yaml.org/spec/1.2/. 34 Documentação e fontes em: http://pyyaml.org/wiki/PyYAML. 136 Persistência 'King Crimson': ['Red', 'Discipline']}, 'Alemanha': {'Kraftwerk': ['Radioactivity', 'Trans Europe Express']} } print yaml.dump(progs) Saída: Alemanha: Kraftwerk: [Radioactivity, Trans Europe Express] Inglaterra: Genesis: [Foxtrot, The Nursery Crime] King Crimson: [Red, Discipline] 'Yes': [Close To The Edge, Fragile] 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: 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) Saída: Persistência 137 [{'musica': 'rock'}, {'cachorro': {'cor': 'Branco', 'nome': 'Bandit', 'raca': 'Labrador'}}, {'outros': {'comida': 'carne', 'instrumento': 'baixo', 'linguagem': ['python', 'ruby']}}] YAML é muito prático para ser usado em arquivos de configuração e outros casos onde os dados podem ser manipulados diretamente por pessoas. 138 Persistência XML XML (eXtensible Markup Language) é uma recomendação, desenvolvida pelo World Wide Web Consortium35 (W3C), para uma representação de dados em que o metadado é armazenado junto com os dados através de marcadores (tags). Em termos estruturais, um arquivo XML representa uma hierarquia formada de elementos, que podem ter ou não atributos ou sub elementos. Características principais: ▪ É legível por software. ▪ Pode ser integrada com outras linguagens. ▪ O conteúdo e a formatação são entidades distintas. ▪ Marcadores podem ser criados sem limitação. ▪ Permite a criação de arquivos para validação de estrutura. No exemplo, o elemento “Cachorro” possui três atributos: nome, raça e cor. O elemento Lobo tem dois sub elementos (“Cachorro” e “Coiote”) e não possui atributos. 35 Página oficial em: http://www.w3.org/. Canino Raposa Cachorro Lobo Coiote Nome: Bandit Raça: Labrador Cor: Branco Atributos Elementos Raiz Árvore de elementos Persistência 139 Em XML, o cachorro é representado por: <Cachorro cor="Branco" nome="Bandit" raca="Labrador" /> E o lobo por: <Lobo> </Lobo> Existem vários módulos de suporte ao XML disponíveis para Python, inclusive na biblioteca que acompanha o interpretador. Entre os mais usados, destacam-se: ▪ DOM. ▪ SAX. ▪ ElementTree. Document Object Model (DOM) é um modelo de objeto para representação de XML, independente de plataforma e linguagem. O DOM foi projetado para permitir navegação não linear e modificações arbitrárias. Por isso, o DOM exige que o documento XML (ou pelo menos parte dele) esteja carregado na memória. Cachorro Nome: Bandit Raça: Labrador Cor: Branco Atributos Tag Elemento Lobo <Cachorro cor="Branco" nome="Bandit" raca="Labrador" /> <Lobo>...</Lobo> 140 Persistência