वस्तुओं को सहेजना और लोड करना और अचार का उपयोग करना


114

मैं pickleमॉड्यूल का उपयोग करके वस्तुओं को बचाने और लोड करने की कोशिश कर रहा हूं ।
पहले मैं अपनी वस्तुओं की घोषणा करता हूं:

>>> class Fruits:pass
...
>>> banana = Fruits()

>>> banana.color = 'yellow'
>>> banana.value = 30

उसके बाद मैंने 'Fruit.obj' नामक एक फ़ाइल खोली (पहले मैंने एक नई .txt फ़ाइल बनाई और मैंने 'Fruit.obj' का नाम बदला):

>>> import pickle
>>> filehandler = open(b"Fruits.obj","wb")
>>> pickle.dump(banana,filehandler)

ऐसा करने के बाद, मैंने अपना सत्र बंद कर दिया और मैंने एक नया शुरू किया और मैंने अगला डाल दिया (उस वस्तु तक पहुँचने की कोशिश करना जो इसे बचाना चाहिए):

file = open("Fruits.obj",'r')
object_file = pickle.load(file)

लेकिन मेरे पास यह संदेश है:

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python31\lib\pickle.py", line 1365, in load
encoding=encoding, errors=errors).load()
ValueError: read() from the underlying stream did notreturn bytes

मुझे नहीं पता कि मुझे क्या करना है क्योंकि मैं इस संदेश को नहीं समझता। क्या किसी को पता है कि मैं अपनी वस्तु 'केला' को कैसे लोड कर सकता हूं? धन्यवाद!

संपादित करें: जैसा कि आप में से कुछ ने मुझे लगाया है:

>>> import pickle
>>> file = open("Fruits.obj",'rb')

कोई समस्या नहीं थी, लेकिन अगले मैं था:

>>> object_file = pickle.load(file)

और मेरे पास त्रुटि है:

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python31\lib\pickle.py", line 1365, in load
encoding=encoding, errors=errors).load()
EOFError


जवाबों:


74

अपनी दूसरी समस्या के रूप में:

 Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 File "C:\Python31\lib\pickle.py", line
 1365, in load encoding=encoding,
 errors=errors).load() EOFError

आपके द्वारा फ़ाइल की सामग्री को पढ़ने के बाद, फ़ाइल पॉइंटर फ़ाइल के अंत में होगा - आगे पढ़ने के लिए कोई डेटा नहीं होगा। आपको फ़ाइल को रिवाइंड करना होगा ताकि वह फिर से शुरू से पढ़ी जाए:

file.seek(0)

हालांकि आप आमतौर पर क्या करना चाहते हैं, यह फ़ाइल खोलने और उससे डेटा पढ़ने के लिए एक संदर्भ प्रबंधक का उपयोग करना है। इस तरह, ब्लॉक को निष्पादित करने के बाद फ़ाइल स्वचालित रूप से बंद हो जाएगी, जिससे आपको अपने फ़ाइल संचालन को सार्थक विखंडनों में व्यवस्थित करने में भी मदद मिलेगी।

अंत में, cPickle C. में अचार मॉड्यूल का तेज़ कार्यान्वयन है।

In [1]: import cPickle

In [2]: d = {"a": 1, "b": 2}

In [4]: with open(r"someobject.pickle", "wb") as output_file:
   ...:     cPickle.dump(d, output_file)
   ...:

# pickle_file will be closed at this point, preventing your from accessing it any further

In [5]: with open(r"someobject.pickle", "rb") as input_file:
   ...:     e = cPickle.load(input_file)
   ...:

In [7]: print e
------> print(e)
{'a': 1, 'b': 2}

यह 'd = {"a": 1, "b": 2}' किस प्रकार की डेटा संरचना है?
पीटरस्टोन 15

1
@Peterstone: {"a": 1, "b": 2}कुंजियों के साथ "a"और "b"इसमें शब्दकोश बनाता है । यह ऑनलाइन प्रलेखन में एक शब्दकोश प्रदर्शन अभिव्यक्ति कहा जाता है । यह कई अलग-अलग तरीकों में से एक है dict, जो ऑब्जेक्ट का एक प्रकार है , जो कि पायथन में उपलब्ध कई मानक बिल्ट-इन डेटाटिप्स में से एक है, जिसका निर्माण किया जा सकता है।
मार्टीन्यू

2
अक्षर 'r' फ़ाइल नाम को क्यों आगे बढ़ाता है? मैं डॉक्स में नहीं देखता हूं। इसके अलावा, फ़ाइल नाम के लिए एक चर का उपयोग करना मुश्किल हो जाता है।
शेरलहोमन

7
आज इस उत्तर को देखते हुए और यह केवल पायथन 2.x पर लागू होता है। पायथन 3.x में, किसी को सीधे उपयोग करना चाहिए pickleजो कि cpickleयदि यह डिब्बे है तो स्वचालित रूप से आयात करेगा। docs.python.org/3.1/whatsnew/3.0.html#library-changes
Eskapp

41

निम्नलिखित मेरे लिए काम करता है:

class Fruits: pass

banana = Fruits()

banana.color = 'yellow'
banana.value = 30

import pickle

filehandler = open("Fruits.obj","wb")
pickle.dump(banana,filehandler)
filehandler.close()

file = open("Fruits.obj",'rb')
object_file = pickle.load(file)
file.close()

print(object_file.color, object_file.value, sep=', ')
# yellow, 30

यह मुझे काम करता है, लेकिन मैं एक सत्र को बंद करने के लिए क्या कर रहा हूं, एक नया खोलें और जो मैं पिछले सत्र में सहेजता हूं उसे लोड करें। मैं "filehandler.close ()" लाइन डालने के बाद सत्र को बंद कर देता हूं और मैं एक नया खोल देता हूं और मैं आपका बाकी कोड डाल देता हूं, फिर "object_file = pickle.load (फाइल)" डालने के बाद मुझे यह त्रुटि मिलती है: Trabackback () सबसे हाल की कॉल अंतिम): फ़ाइल "<pyshell # 5>", पंक्ति 1, में <मॉड्यूल> object_file = pickle.load (फ़ाइल) फ़ाइल "C: \ Python31 \ lib \ pickle.py", पंक्ति 1365, लोड एन्कोडिंग में = एन्कोडिंग, त्रुटियां = त्रुटियां) .load () विशेषता: 'मॉड्यूल' ऑब्जेक्ट में कोई विशेषता 'फल' नहीं है
पीटरस्टोन

3
@ पेटरस्टोन: दूसरे सत्र में आपको class Fruitsपरिभाषित की परिभाषा की आवश्यकता होगी ताकि pickle.load()बाइनरी फ़ाइल में सहेजे गए डेटा से ऑब्जेक्ट को पुनर्गठित किया जा सके। इस तरह की चीज़ के लिए सबसे अच्छा अभ्यास है class Fruitsपरिभाषा को एक अलग .py फ़ाइल (इसे एक कस्टम मॉड्यूल बनाना) और फिर importउस मॉड्यूल या आइटम को जब भी ज़रूरत हो (यानी दोनों सत्रों)। उदाहरण के लिए यदि आप इसे किसी फ़ाइल में रखते हैं, MyDataDefs.pyतो आप लिख सकते हैं from MyDataDefs import Fruits। मुझे बताएं कि क्या यह अस्पष्ट है और मैं तदनुसार अपना उत्तर अपडेट करूंगा।
20

वास्तव में पीईपी 8 मॉड्यूल नामों के लिए सभी लोअरकेस वर्णों का उपयोग करने की सिफारिश करता है , इसलिए मेरी अंतिम टिप्पणी के अंत में उदाहरण my_data_defs.pyका उपयोग करके किसी फ़ाइल में होना चाहिए from my_data_defs import Fruits
मार्टीन्यू

24

आप इसे बाइनरी के रूप में भी पढ़ना भूल रहे हैं।

आपके लेखन भाग में आपके पास है:

open(b"Fruits.obj","wb") # Note the wb part (Write Binary)

आपके पास पढ़ने वाले हिस्से में:

file = open("Fruits.obj",'r') # Note the r part, there should be a b too

तो इसे इसके साथ बदलें:

file = open("Fruits.obj",'rb')

और यह काम करेगा :)


आपकी दूसरी त्रुटि के रूप में, यह फ़ाइल को ठीक से बंद / सिंक्रनाइज़ नहीं करने के कारण सबसे अधिक संभावना है।

इस कोड को लिखने की कोशिश करें:

>>> import pickle
>>> filehandler = open(b"Fruits.obj","wb")
>>> pickle.dump(banana,filehandler)
>>> filehandler.close()

और यह (अपरिवर्तित) पढ़ने के लिए:

>>> import pickle
>>> file = open("Fruits.obj",'rb')
>>> object_file = pickle.load(file)

एक नेटर संस्करण withबयान का उपयोग किया जाएगा ।

लिखने के लिये:

>>> import pickle
>>> with open('Fruits.obj', 'wb') as fp:
>>>     pickle.dump(banana, fp)

पढ़ने के लिए:

>>> import pickle
>>> with open('Fruits.obj', 'rb') as fp:
>>>     banana = pickle.load(fp)

1
मैं आपके संस्करण का उपयोग करता हूं जो कथन के साथ उपयोग करता है और मुझे यह संदेश प्राप्त होता है: ट्रेसबैक (सबसे हालिया कॉल अंतिम): फ़ाइल "<pyshell # 20>", पंक्ति 1, में <मॉड्यूल> प्रिंट (banana.color) गुणक 'गुण' ऑब्जेक्ट का कोई विशेषता 'रंग' नहीं है
पीटरस्टोन


6

आपने फ़ाइल को बाइनरी मोड में नहीं खोला है।

open("Fruits.obj",'rb')

कार्य करना चाहिए।

आपकी दूसरी त्रुटि के लिए, फ़ाइल सबसे अधिक संभावना खाली है, जिसका अर्थ है कि आपने अनजाने में इसे खाली कर दिया है या गलत फ़ाइलनाम या कुछ का उपयोग किया है।

(यह मानकर चला गया है कि आपने वास्तव में अपना सत्र बंद कर दिया है। यदि नहीं, तो यह इसलिए है क्योंकि आपने लिखने और पढ़ने के बीच फाइल बंद नहीं की है)।

मैंने आपके कोड का परीक्षण किया, और यह काम करता है।


3

ऐसा लगता है कि आप सत्रों में अपने वर्ग के उदाहरणों को सहेजना चाहते हैं, और इसका उपयोग pickleकरना एक अच्छा तरीका है। हालाँकि, एक पैकेज है जिसे kleptoएब्स्ट्रैक्ट टू डिक्शनरी इंटरफ़ेस कहा जाता है, इसलिए आप अचार वस्तुओं को चुन सकते हैं और उन्हें एक फ़ाइल में सहेज सकते हैं (जैसा कि नीचे दिखाया गया है), या ऑब्जेक्ट्स को अचार करके या डेटाबेस में रखने के बजाय उन्हें सेव करें। अचार का उपयोग करें, या अन्य कई विकल्पों का उपयोग करें। अच्छी बात है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('fruits.txt')
>>> class Fruits: pass
... 
>>> banana = Fruits()
>>> banana.color = 'yellow'
>>> banana.value = 30
>>> 
>>> db['banana'] = banana 
>>> 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('fruits.txt')
>>> db.load()
>>> 
>>> db['banana'].color
'yellow'
>>> 

Klepto python2 और python3 पर काम करता है।

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


1

आप अपने लिए काम करने के लिए किसी भी प्रकार के कैश का उपयोग कर सकते हैं । मान लें कि आपके पास एक फ़ंक्शन है myfuncजो उदाहरण बनाता है:

from anycache import anycache

class Fruits:pass

@anycache(cachedir='/path/to/your/cache')    
def myfunc()
    banana = Fruits()
    banana.color = 'yellow'
    banana.value = 30
return banana

एनाकाच myfuncपहली बार कॉल cachedirकरता है और फ़ाइलनाम के रूप में एक अद्वितीय पहचानकर्ता (फ़ंक्शन के नाम और तर्कों के आधार पर) का उपयोग करके एक फ़ाइल के परिणाम को अचार करता है। किसी भी लगातार चलने पर, पिक की गई वस्तु लोड हो जाती है।

यदि cachedirअजगर रनों के बीच संरक्षित है, तो पिक्स्ड ऑब्जेक्ट को पिछले पायथन रन से लिया जाता है।

फ़ंक्शन तर्क को भी ध्यान में रखा जाता है। इसी तरह एक कार्यान्वित कार्यान्वयन कार्य करता है:

from anycache import anycache

class Fruits:pass

@anycache(cachedir='/path/to/your/cache')    
def myfunc(color, value)
    fruit = Fruits()
    fruit.color = color
    fruit.value = value
return fruit
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.