Serialização Python - Por que pickle?

87

Eu entendi que o pickling Python é uma maneira de 'armazenar' um objeto Python de uma maneira que respeita a programação de objeto - diferente de uma saída escrita em arquivo txt ou banco de dados.

Você tem mais detalhes ou referências sobre os seguintes pontos:

  • onde os objetos em conserva são 'armazenados'?
  • por que conservar está preservando a representação do objeto mais do que, digamos, armazenar no banco de dados?
  • posso recuperar objetos em conserva de uma sessão de shell Python para outra?
  • você tem exemplos significativos em que a serialização é útil?
  • a serialização com pickle implica 'compressão' de dados?

Em outras palavras, estou procurando um documento sobre pickling - Python.doc explica como implementar pickle, mas parece não entrar em detalhes sobre o uso e a necessidade de serialização.

Kiriloff
fonte
Para salvar o estado para restauração posterior ou para compartilhar / copiar um objeto para um Python runtime diferente, seria o meu palpite.
synthesizerpatel
13
Muitas de suas perguntas foram respondidas pelo artigo da Wikipedia sobre serialização: en.wikipedia.org/wiki/Serialization
NPE
5
você está perguntando por que eu precisaria do Pickle para serialização em Python? ou melhor, qual é (o propósito da) serialização afinal? .
moooeeeep
Talvez seja bom mencionar os problemas de segurança com picles. Exemplos podem ser encontrados nos documentos e em várias perguntas do SO, como esta .
djvg de

Respostas:

99

Pickling é uma forma de converter um objeto Python (lista, dict, etc.) em um fluxo de caracteres. A ideia é que esse fluxo de caracteres contenha todas as informações necessárias para reconstruir o objeto em outro script Python.

Quanto ao local onde as informações em conserva são armazenadas, normalmente se faria:

with open('filename', 'wb') as f:
    var = {1 : 'a' , 2 : 'b'}
    pickle.dump(var, f)

Isso armazenaria a versão em conserva de nosso vardicionário no arquivo 'filename'. Então, em outro script, você poderia carregar a partir desse arquivo em uma variável e o dicionário seria recriado:

with open('filename','rb') as f:
    var = pickle.load(f)

Outro uso para decapagem é se você precisar transmitir este dicionário através de uma rede (talvez com soquetes ou algo assim). Primeiro você precisa convertê-lo em um fluxo de caracteres e, em seguida, pode enviá-lo por uma conexão de soquete.

Além disso, não há "compressão" para falar aqui ... é apenas uma maneira de converter de uma representação (em RAM) para outra (em "texto").

About.com tem uma boa introdução sobre decapagem aqui .

Austin1howard
fonte
2
normalmente fariawith open('filename') as f: ...
moooeeeep
3
Além disso, você precisaria fazer with open(filename, 'wb') as f: ...ou não seria capaz de gravar no arquivo.
Tim Pietzcker
Obrigado!! Este aqui sobre gerenciamento de persistência em Python é bom, aqui
Kiriloff
1
Em geral, não é uma ideia muito boa usar picklepara transmitir um dicionário em uma rede (json poderia ser melhor aqui). Embora em casos raros possa ser útil, por exemplo, multiprocessingmódulo.
jfs
@Tim Pietzcker: protocol=0(padrão em Python2.x) pode ser usado com arquivos abertos em modo texto.
jfs
36

A decapagem é absolutamente necessária para computação distribuída e paralela.

Digamos que você queira fazer uma redução de mapa paralela com multiprocessing(ou entre nós de cluster com pyina ), então você precisa ter certeza de que a função que deseja mapear nos recursos paralelos ficará em funcionamento. Se ele não funcionar, você não poderá enviá-lo para outros recursos em outro processo, computador, etc. Veja aqui também um bom exemplo.

Para fazer isso, eu uso o dill , que pode serializar quase tudo em python. O Dill também tem algumas boas ferramentas para ajudá-lo a entender o que está causando a falha do seu decapagem quando o código falha.

E, sim, as pessoas usam o picking para salvar o estado de um cálculo, ou sua sessão ipython , ou qualquer outra coisa. Você também pode estender Pickler e UnPickler do pickle para fazer compressão com bz2ou gzipse desejar.

Mike McKerns
fonte
0

Acho que é particularmente útil com classes personalizadas grandes e complexas. Em um exemplo particular que estou pensando, "Coletar" as informações (de um banco de dados) para criar a classe já foi metade da batalha. Então, essas informações armazenadas na classe podem ser alteradas no tempo de execução pelo usuário.

Você poderia ter outro grupo de tabelas no banco de dados e escrever outra função para percorrer tudo armazenado e gravá-lo nas novas tabelas do banco de dados. Então, você precisaria escrever outra função para poder carregar algo salvo lendo todas essas informações de volta.

Como alternativa, você pode selecionar toda a classe como está e armazená-la em um único campo no banco de dados. Então, quando você for carregá-lo de volta, tudo carregará de volta ao mesmo tempo, como era antes. Isso pode acabar economizando muito tempo e código ao salvar e recuperar classes complicadas.

Frango Max
fonte
-1

é uma espécie de serialização. usar cPickle é muito mais rápido que pickle.

import pickle
##make Pickle File
with open('pickles/corups.pickle', 'wb') as handle:
    pickle.dump(corpus, handle)

#read pickle file
with open('pickles/corups.pickle', 'rb') as handle:
    corpus = pickle.load(handle)
Paritosh Yadav
fonte