मैं अजगर में कई चर कैसे बचाऊं और पुनर्स्थापित करूं?


105

मुझे एक दर्जन वस्तुओं को एक फ़ाइल में सहेजने और बाद में उन्हें पुनर्स्थापित करने की आवश्यकता है। मैंने अचार और सेव के साथ लूप के लिए उपयोग करने की कोशिश की है, लेकिन यह सही काम नहीं किया।

संपादित करें।
जिन वस्तुओं को मैं बचाने की कोशिश कर रहा था, वे सभी एक ही कक्षा में थीं (मुझे पहले भी इसका उल्लेख करना चाहिए था), और मुझे इस बात का एहसास नहीं था कि मैं पूरी कक्षा को इस तरह बचा सकता हूँ:

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
आप कहते हैं कि आपने पाश के लिए प्रयास किया है। कृपया उस कोड को पोस्ट करें, और "यह सही काम क्यों नहीं किया" (यानी, क्या हुआ और आप क्या करना चाहते थे)।
ब्लेयर

यदि आप खिड़कियों पर हैं, तो बाइनरी मोड में फ़ाइलों को खोलना सुनिश्चित करें
जॉन ला रूय जूल

@gnibbler: बाइनरी मोड केवल गैर-डिफ़ॉल्ट प्रोटोकॉल ( docs.python.org/library/pickle.html#usage ) के लिए आवश्यक है।
एरिक ओ लेबिगॉट

जवाबों:


170

यदि आपको कई वस्तुओं को सहेजने की आवश्यकता है, तो आप उन्हें उदाहरण के लिए किसी एकल सूची या टपल में रख सकते हैं:

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)

आप डेटा का एक बहुत है, तो आप को पारित करके फ़ाइल आकार कम कर सकते हैं protocol=-1करने के लिए dump(); pickleफिर डिफ़ॉल्ट ऐतिहासिक (और अधिक पिछड़े-संगत) प्रोटोकॉल के बजाय सर्वोत्तम उपलब्ध प्रोटोकॉल का उपयोग करेगा। इस स्थिति में, फ़ाइल को बाइनरी मोड में खोला जाना चाहिए ( wbऔर rb, क्रमशः)।

बाइनरी मोड का उपयोग पायथन 3 के साथ भी किया जाना चाहिए, क्योंकि इसका डिफ़ॉल्ट प्रोटोकॉल बाइनरी (यानी गैर-पाठ) डेटा (लेखन मोड 'wb'और रीडिंग मोड 'rb') का उत्पादन करता है।


12
पायथन 3.5 में, मुझे फ़ाइल को "बाइट" मोड में खोलना था, उदाहरण के लिए with open('objs.pickle', 'wb') as f:(नोट करें wb)।
kbrose

हाय @ ईरिक, with open('objs.pkl') as f:बस की तुलना करने की आवश्यकता क्या है obj1, obj2 = pickle.load(open("objs.pkl","rb"))? क्या इन दोनों में कोई अंतर है?
बाल्डॉन्गिव जूल

दूसरे फॉर्म के साथ आप फाइल को बंद न करें। यह अच्छा अभ्यास नहीं माना जाता है, क्योंकि समानांतर में आपके द्वारा खोली जा सकने वाली फ़ाइलों की संख्या आमतौर पर ऑपरेटिंग सिस्टम द्वारा काफी सीमित होती है (एक पाश की कोशिश करें जो फ़ाइलों को बंद किए बिना खोलती है!)। कहा कि, व्यवहार में, फ़ाइल को बंद करना अक्सर काम नहीं करता है, जब आप कई फाइलें नहीं खोलते हैं।
एरिक ओ लेबिगॉट

51

एक अंतर्निहित पुस्तकालय कहा जाता है pickle। उपयोग करने से pickleआप किसी फ़ाइल में ऑब्जेक्ट डंप कर सकते हैं और बाद में लोड कर सकते हैं।

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 पायथन 3.4 का उपयोग करें: f = open('store.pckl', 'wb')लिखने के लिए फ़ाइल खोलने के लिए। का संदर्भ लें stackoverflow.com/questions/13906623/... और उपयोग `च = खुला ( 'store.pckl', 'rb') से पढ़ने के लिए एक फ़ाइल खोलने के लिए। का संदर्भ लें stackoverflow.com/questions/7031699/...
user3731622

क्या यह 3.4+ के लिए विशिष्ट है? जब मैंने 'b' का उपयोग नहीं किया, तो मैंने लगभग जवाब को वोट दिया क्योंकि यह त्रुटियां उत्पन्न करता है।
विल्मर ई। हेनो

12

आपको शेल्व और अचार मॉड्यूल को देखना चाहिए । यदि आपको बहुत अधिक डेटा संग्रहीत करने की आवश्यकता है, तो डेटाबेस का उपयोग करना बेहतर हो सकता है


मैं एक एकल ऑब्जेक्ट को सहेजना चाहता हूं जो एक क्लाउड सर्वर में लॉग इन करता है, यह संभालने के लिए कि क्या मैं समय के साथ कई बार लॉगिन करता हूं, सर्वर मेरे अनुरोध को अस्वीकार कर देता है। अचार मॉड्यूल का उपयोग करके किसी ऑब्जेक्ट को फ़ाइल में डंप करने से कोई सुरक्षा समस्या हो सकती है? , उदाहरण के लिए यदि कोई मेरी डंप की गई वस्तु प्राप्त करता है, तो वे पासवर्ड का उपयोग किए बिना मेरे क्लाउड-स्टोरेज में प्रवेश कर सकते हैं।
अल्पर

5

अचार फ़ाइल में कई चर बचाने के लिए एक और तरीका है:

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

आप उपयोग कर सकते हैं klepto, जो मेमोरी, डिस्क या डेटाबेस को लगातार कैशिंग प्रदान करता है।

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()
>>> 

फिर, दुभाषिया पुनरारंभ होने के बाद ...

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
>>> 

यहां कोड प्राप्त करें: https://github.com/uqfoundation


7
ओपी ने बिल्ट-इन नहीं मांगा।
माइक मैकेर्न

4

निम्नलिखित दृष्टिकोण सरल लगता है और विभिन्न आकार के चर के साथ इस्तेमाल किया जा सकता है:

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)

hickleपैकेज अधिक मजबूत (कम त्रुटि वाला) और यहां तक ​​कि सरल (कम कोड) की तुलना में अधिक मजबूत है pickle
user2340939
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.