Python'da birden çok değişkeni nasıl kaydeder ve geri yüklerim?


107

Yaklaşık bir düzine nesneyi bir dosyaya kaydetmem ve daha sonra geri yüklemem gerekiyor. Turşu ve raf ile bir for döngüsü kullanmayı denedim ama doğru çalışmadı.

Düzenle.
Kurtarmaya çalıştığım tüm nesneler aynı sınıftaydı (bundan daha önce bahsetmeliydim) ve tüm sınıfı böyle kurtarabileceğimi fark etmemiştim:

import pickle
def saveLoad(opt):
    global calc
    if opt == "save":
        f = file(filename, 'wb')
        pickle.dump(calc, f, 2)
        f.close
        print 'data saved'
    elif opt == "load":
        f = file(filename, 'rb')
        calc = pickle.load(f)
    else:
        print 'Invalid saveLoad option'

1
Bir for döngüsü denediğini söylüyorsun. Lütfen bu kodu ve neden "doğru çalışmadığını" (yani, ne olduğunu ve ne olmasını istediğinizi) gönderin.
Blair

Windows'taysanız, dosyaları ikili modda açtığınızdan emin olun
John La Rooy

@gnibbler: ikili mod yalnızca varsayılan olmayan protokoller için gereklidir ( docs.python.org/library/pickle.html#usage ).
Eric O Lebigot

Yanıtlar:


173

Birden fazla nesneyi kaydetmeniz gerekiyorsa, bunları tek bir listeye veya tuple'a koyabilirsiniz, örneğin:

import pickle

# obj0, obj1, obj2 are created here...

# Saving the objects:
with open('objs.pkl', 'w') as f:  # Python 3: open(..., 'wb')
    pickle.dump([obj0, obj1, obj2], f)

# Getting back the objects:
with open('objs.pkl') as f:  # Python 3: open(..., 'rb')
    obj0, obj1, obj2 = pickle.load(f)

Eğer çok fazla veri varsa, ileterek dosya boyutunu azaltabilir protocol=-1için dump(); pickledaha sonra varsayılan tarihsel (ve daha geriye dönük uyumlu) protokol yerine mevcut en iyi protokolü kullanacaktır. Bu durumda, dosya ikili modda ( wbve rbsırasıyla) açılmalıdır .

İkili mod, varsayılan protokolü ikili (yani metin olmayan) veri (yazma modu 'wb've okuma modu 'rb') ürettiğinden, Python 3 ile de kullanılmalıdır .


12
Python 3.5'te, dosyayı "bayt" modunda açmak zorunda kaldım, örneğin with open('objs.pickle', 'wb') as f:(not edin wb).
kbrose

Merhaba @Eric, with open('objs.pkl') as f:basitçe karşılaştırmaya ne gerek var obj1, obj2 = pickle.load(open("objs.pkl","rb"))? Bu ikisi arasında bir fark var mı?
balandongiv

İkinci form ile dosyayı kapatmazsınız. Paralel olarak açabileceğiniz dosyaların sayısı genellikle işletim sistemleri tarafından oldukça sınırlı olduğundan bu, iyi bir uygulama olarak kabul edilmez (dosyaları kapatmadan açan bir döngü deneyin!). Bununla birlikte, pratikte, çok sayıda dosyayı açmadığınızda, dosyayı kapatmamak genellikle işe yarar.
Eric O Lebigot

51

Adlı yerleşik bir kitaplık var pickle. Kullanarak picklenesneleri bir dosyaya dökebilir ve daha sonra yükleyebilirsiniz.

import pickle

f = open('store.pckl', 'wb')
pickle.dump(obj, f)
f.close()

f = open('store.pckl', 'rb')
obj = pickle.load(f)
f.close()

1
I Python 3.4 şunu kullan: f = open('store.pckl', 'wb')yazmak için bir dosya açmak için. Stackoverflow.com/questions/13906623/… adresine bakın ve okumak üzere bir dosyayı açmak için "f = open ('store.pckl', 'rb') kullanın. Stackoverflow.com/questions/7031699/… adresine bakın .
user3731622

bu 3.4+ sürümüne özel mi? Neredeyse yanıtı reddettim çünkü 'b' kullanmadığınızda hata veriyor.
Wilmer E. Henao

12

Raf ve turşu modüllerine bakmalısınız . Çok fazla veri depolamanız gerekiyorsa, bir veritabanı kullanmak daha iyi olabilir


Zaman içinde birden çok kez oturum açarsam işlemek için bir bulut sunucusunda oturum açan tek bir nesneyi kaydetmek istiyorum, sunucu isteğimi reddediyor. Pickle modülünü kullanarak bir nesneyi bir dosyaya dökmek herhangi bir güvenlik sorunu yaratabilir mi? Örneğin, birisi atılan nesnemi elde ederse, bulut depolama alanıma şifre kullanmadan giriş yapabilir.
alper

6

Birden çok değişkeni bir turşu dosyasına kaydetmenin başka bir yolu:

import pickle

a = 3; b = [11,223,435];
pickle.dump([a,b], open("trial.p", "wb"))

c,d = pickle.load(open("trial.p","rb"))

print(c,d) ## To verify

4

kleptoBelleğe, diske veya veritabanına kalıcı önbelleğe alma sağlayan kullanabilirsiniz .

dude@hilbert>$ python
Python 2.7.6 (default, Nov 12 2013, 13:26:39) 
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from klepto.archives import file_archive
>>> db = file_archive('foo.txt')
>>> db['1'] = 1
>>> db['max'] = max
>>> squared = lambda x: x**2
>>> db['squared'] = squared
>>> def add(x,y):
...   return x+y
... 
>>> db['add'] = add
>>> class Foo(object):
...   y = 1
...   def bar(self, x):
...     return self.y + x
... 
>>> db['Foo'] = Foo
>>> f = Foo()
>>> db['f'] = f  
>>> db.dump()
>>> 

Ardından, tercüman yeniden başlatıldıktan sonra ...

dude@hilbert>$ python
Python 2.7.6 (default, Nov 12 2013, 13:26:39) 
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from klepto.archives import file_archive
>>> db = file_archive('foo.txt')
>>> db
file_archive('foo.txt', {}, cached=True)
>>> db.load()
>>> db
file_archive('foo.txt', {'1': 1, 'add': <function add at 0x10610a0c8>, 'f': <__main__.Foo object at 0x10510ced0>, 'max': <built-in function max>, 'Foo': <class '__main__.Foo'>, 'squared': <function <lambda> at 0x10610a1b8>}, cached=True)
>>> db['add'](2,3)
5
>>> db['squared'](3)
9
>>> db['f'].bar(4)
5
>>> 

Kodu buradan alın: https://github.com/uqfoundation


7
OP yerleşik istemedi.
Mike McKerns

4

Aşağıdaki yaklaşım basit görünmektedir ve farklı büyüklükteki değişkenlerle kullanılabilir:

import hickle as hkl
# write variables to filename [a,b,c can be of any size]
hkl.dump([a,b,c], filename)

# load variables from filename
a,b,c = hkl.load(filename)

hicklepaket pickle,.
user2340939
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.