मैंने इस तरह एक वस्तु बनाई है:
company1.name = 'banana'
company1.value = 40
मैं इस वस्तु को बचाना चाहूंगा। मैं उसे कैसे कर सकता हूँ?
protocol=pickle.HIGHEST_PROTOCOL। मेरा जवाब अचार का विकल्प भी देता है।
मैंने इस तरह एक वस्तु बनाई है:
company1.name = 'banana'
company1.value = 40
मैं इस वस्तु को बचाना चाहूंगा। मैं उसे कैसे कर सकता हूँ?
protocol=pickle.HIGHEST_PROTOCOL। मेरा जवाब अचार का विकल्प भी देता है।
जवाबों:
आप pickleमानक पुस्तकालय में मॉड्यूल का उपयोग कर सकते हैं । यहां इसका एक प्राथमिक अनुप्रयोग आपके उदाहरण के लिए दिया गया है:
import pickle
class Company(object):
def __init__(self, name, value):
self.name = name
self.value = value
with open('company_data.pkl', 'wb') as output:
company1 = Company('banana', 40)
pickle.dump(company1, output, pickle.HIGHEST_PROTOCOL)
company2 = Company('spam', 42)
pickle.dump(company2, output, pickle.HIGHEST_PROTOCOL)
del company1
del company2
with open('company_data.pkl', 'rb') as input:
company1 = pickle.load(input)
print(company1.name) # -> banana
print(company1.value) # -> 40
company2 = pickle.load(input)
print(company2.name) # -> spam
print(company2.value) # -> 42
आप निम्न की तरह अपनी स्वयं की सरल उपयोगिता को भी परिभाषित कर सकते हैं जो एक फ़ाइल को खोलता है और इसके लिए एक एकल ऑब्जेक्ट लिखता है:
def save_object(obj, filename):
with open(filename, 'wb') as output: # Overwrites any existing file.
pickle.dump(obj, output, pickle.HIGHEST_PROTOCOL)
# sample usage
save_object(company1, 'company1.pkl')
चूंकि यह इतना लोकप्रिय उत्तर है, इसलिए मैं कुछ उन्नत उपयोग विषयों पर स्पर्श करना चाहूंगा।
cPickle(या _pickle) बनामpickleयह लगभग हमेशा बेहतर होता है कि वास्तव में cPickleमॉड्यूल का उपयोग करें, बजाय इसके pickleकि पूर्व को C में लिखा गया है और बहुत तेज है। उनके बीच कुछ सूक्ष्म अंतर हैं, लेकिन ज्यादातर स्थितियों में वे समकक्ष हैं और सी संस्करण बहुत बेहतर प्रदर्शन प्रदान करेगा। इसे स्विच करना आसान नहीं हो सकता है, बस importस्टेटमेंट को इस में बदलें :
import cPickle as pickle
पायथन 3 में, cPickleका नाम बदल दिया गया था _pickle, लेकिन ऐसा करना अब आवश्यक नहीं है क्योंकि pickleमॉड्यूल अब स्वचालित रूप से करता है - देखें कि पायथन 3 में अचार और _pickle के बीच क्या अंतर है? ।
यह सुनिश्चित करने के लिए कि आप अपने कोड को हमेशा C संस्करण का उपयोग करेंगे जब यह पायथन 2 और 3 दोनों में उपलब्ध होगा:
try:
import cPickle as pickle
except ModuleNotFoundError:
import pickle
pickleकई अलग-अलग, पायथन-विशिष्ट, स्वरूपों में फ़ाइलों को पढ़ और लिख सकते हैं, जिन्हें दस्तावेज में वर्णित प्रोटोकॉल कहा जाता है , "प्रोटोकॉल संस्करण 0" ASCII है और इसलिए "मानव-पठनीय" है। संस्करण> 0 द्विआधारी हैं और उपलब्ध सबसे अधिक यह निर्भर करता है कि पायथन के किस संस्करण का उपयोग किया जा रहा है। डिफ़ॉल्ट भी पायथन संस्करण पर निर्भर करता है। पायथन 2 में डिफ़ॉल्ट प्रोटोकॉल संस्करण था , लेकिन पायथन 3.8.1 में, यह प्रोटोकॉल संस्करण है । पायथन 3.x में मॉड्यूल को इसमें जोड़ा गया था, लेकिन यह पायथन 2 में मौजूद नहीं है।04pickle.DEFAULT_PROTOCOL
सौभाग्य से pickle.HIGHEST_PROTOCOLहर कॉल में लिखने के लिए आशुलिपि है (यह मानते हुए कि आप क्या चाहते हैं, और आप आमतौर पर करते हैं), बस शाब्दिक संख्या का उपयोग करें -1- एक नकारात्मक सूचकांक के माध्यम से अनुक्रम के अंतिम तत्व को संदर्भित करने के समान। इसलिए, लिखने के बजाय:
pickle.dump(obj, output, pickle.HIGHEST_PROTOCOL)
आप बस लिख सकते हैं:
pickle.dump(obj, output, -1)
किसी भी तरह से, आप केवल एक बार प्रोटोकॉल का उल्लेख करेंगे यदि आपने Picklerकई अचार के संचालन में उपयोग के लिए एक वस्तु बनाई है :
pickler = pickle.Pickler(output, -1)
pickler.dump(obj1)
pickler.dump(obj2)
etc...
नोट : यदि आप पाइथन के विभिन्न संस्करणों को चलाने वाले वातावरण में हैं, तो आप शायद एक विशिष्ट प्रोटोकॉल संख्या का स्पष्ट रूप से उपयोग करना चाहते हैं (अर्थात हार्डकोड) जो कि सभी पढ़ सकते हैं (बाद के संस्करण आम तौर पर पहले वाले द्वारा उत्पादित फ़ाइलों को पढ़ सकते हैं) ।
एक अचार फ़ाइल जबकि कर सकते हैं जैसा कि ऊपर के नमूने में दिखाया गया है जब उनमें से एक अज्ञात नंबर है मसालेदार वस्तुओं के किसी भी संख्या, होते हैं, यह अक्सर उन सब को, variably आकार कंटेनर के कुछ प्रकार में स्टोर करने के लिए एक तरह आसान है list, tupleया dictऔर लिखने उन सभी को एक कॉल में फाइल करने के लिए:
tech_companies = [
Company('Apple', 114.18), Company('Google', 908.60), Company('Microsoft', 69.18)
]
save_object(tech_companies, 'tech_companies.pkl')
और सूची और बाद में इसके साथ सब कुछ बहाल करें:
with open('tech_companies.pkl', 'rb') as input:
tech_companies = pickle.load(input)
प्रमुख लाभ (हालांकि उस जानकारी के बिना ऐसा करने से आप को पता है कि कितने वस्तु उदाहरणों ताकि उन्हें बाद में वापस लोड करने के लिए में सहेजे जाते हैं की जरूरत नहीं है है है संभव है, यह कुछ थोड़ा विशेष कोड की आवश्यकता है)। संबंधित प्रश्न के उत्तर देखें अचार फ़ाइल में कई वस्तुओं को सहेजना और लोड करना? ऐसा करने के विभिन्न तरीकों के विवरण के लिए। व्यक्तिगत रूप से मुझे @Lutz Prechelt का उत्तर सबसे अच्छा लगता है। इसे यहाँ उदाहरण के लिए अनुकूलित किया गया है:
class Company:
def __init__(self, name, value):
self.name = name
self.value = value
def pickled_items(filename):
""" Unpickle a file of pickled data. """
with open(filename, "rb") as f:
while True:
try:
yield pickle.load(f)
except EOFError:
break
print('Companies in pickle file:')
for company in pickled_items('company_data.pkl'):
print(' name: {}, value: {}'.format(company.name, company.value))
company1और company2। आप भी क्यों नहीं हटाते हैं Companyऔर दिखाते हैं कि क्या होता है?
मुझे लगता है कि यह एक बहुत मजबूत धारणा है कि ऑब्जेक्ट एक है class। अगर यह नहीं है तो क्या होगा class? यह भी धारणा है कि वस्तु दुभाषिया में परिभाषित नहीं की गई थी। क्या होगा अगर यह दुभाषिया में परिभाषित किया गया था? इसके अलावा, क्या होगा यदि विशेषताओं को गतिशील रूप से जोड़ा गया हो? जब कुछ अजगर वस्तुओं के __dict__निर्माण के बाद उनकी विशेषताओं को जोड़ा जाता है , pickleतो उन विशेषताओं के जोड़ का सम्मान नहीं करता है (अर्थात यह 'भूल जाता है' उन्हें जोड़ा गया था - क्योंकि pickleऑब्जेक्ट परिभाषा के संदर्भ में क्रमबद्ध है)।
इन सभी मामलों में, pickleऔर cPickleआपको बुरी तरह से विफल कर सकता है।
यदि आप एक object(मनमाने ढंग से बनाई गई) को बचाने के लिए देख रहे हैं , जहां आपके पास विशेषताएँ हैं (या तो ऑब्जेक्ट परिभाषा में, या बाद में जोड़ा गया है) ... आपका सबसे अच्छा शर्त उपयोग करना है dill, जो अजगर में लगभग कुछ भी सीरियल कर सकता है।
हम एक वर्ग से शुरू करते हैं ...
Python 2.7.8 (default, Jul 13 2014, 02:29:54)
[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.
>>> import pickle
>>> class Company:
... pass
...
>>> company1 = Company()
>>> company1.name = 'banana'
>>> company1.value = 40
>>> with open('company.pkl', 'wb') as f:
... pickle.dump(company1, f, pickle.HIGHEST_PROTOCOL)
...
>>>
अब शट डाउन, और पुनः आरंभ करें ...
Python 2.7.8 (default, Jul 13 2014, 02:29:54)
[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.
>>> import pickle
>>> with open('company.pkl', 'rb') as f:
... company1 = pickle.load(f)
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1378, in load
return Unpickler(file).load()
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 858, in load
dispatch[key](self)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1090, in load_global
klass = self.find_class(module, name)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1126, in find_class
klass = getattr(mod, name)
AttributeError: 'module' object has no attribute 'Company'
>>>
ओह ... pickleइसे संभाल नहीं सकते। आइए कोशिश करते हैं dill। हम lambdaअच्छे उपाय के लिए दूसरे ऑब्जेक्ट प्रकार (ए ) में फेंक देंगे ।
Python 2.7.8 (default, Jul 13 2014, 02:29:54)
[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.
>>> import dill
>>> class Company:
... pass
...
>>> company1 = Company()
>>> company1.name = 'banana'
>>> company1.value = 40
>>>
>>> company2 = lambda x:x
>>> company2.name = 'rhubarb'
>>> company2.value = 42
>>>
>>> with open('company_dill.pkl', 'wb') as f:
... dill.dump(company1, f)
... dill.dump(company2, f)
...
>>>
और अब फाइल को पढ़ें।
Python 2.7.8 (default, Jul 13 2014, 02:29:54)
[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.
>>> import dill
>>> with open('company_dill.pkl', 'rb') as f:
... company1 = dill.load(f)
... company2 = dill.load(f)
...
>>> company1
<__main__.Company instance at 0x107909128>
>>> company1.name
'banana'
>>> company1.value
40
>>> company2.name
'rhubarb'
>>> company2.value
42
>>>
यह काम करता हैं। कारण pickleविफल हो जाता है, और dillऐसा नहीं होता है, यह एक मॉड्यूल (अधिकांश भाग के लिए) की तरह dillव्यवहार करता है __main__, और संदर्भ द्वारा अचार के बजाय वर्ग परिभाषाएं भी चुन सकता है (जैसे pickleकरता है)। कारणdill अचार lambdaहै कि यह इसे एक नाम देता है ... फिर जादू का अचार हो सकता है।
दरअसल, इन सभी वस्तुओं को सहेजने का एक आसान तरीका है, खासकर यदि आपके पास बहुत सी वस्तुएं हैं जो आपने बनाई हैं। बस पूरे अजगर सत्र को डंप करें, और बाद में वापस आ जाएं।
Python 2.7.8 (default, Jul 13 2014, 02:29:54)
[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.
>>> import dill
>>> class Company:
... pass
...
>>> company1 = Company()
>>> company1.name = 'banana'
>>> company1.value = 40
>>>
>>> company2 = lambda x:x
>>> company2.name = 'rhubarb'
>>> company2.value = 42
>>>
>>> dill.dump_session('dill.pkl')
>>>
अब अपने कंप्यूटर को बंद करें, एक एस्प्रेसो या जो भी हो, का आनंद लें और बाद में वापस आएं ...
Python 2.7.8 (default, Jul 13 2014, 02:29:54)
[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.
>>> import dill
>>> dill.load_session('dill.pkl')
>>> company1.name
'banana'
>>> company1.value
40
>>> company2.name
'rhubarb'
>>> company2.value
42
>>> company2
<function <lambda> at 0x1065f2938>
एकमात्र बड़ी कमी यह है कि dillअजगर मानक पुस्तकालय का हिस्सा नहीं है। इसलिए यदि आप अपने सर्वर पर एक अजगर पैकेज स्थापित नहीं कर सकते हैं, तो आप इसका उपयोग नहीं कर सकते।
हालांकि, अगर आप अपने सिस्टम पर अजगर पैकेज इंस्टॉल करने में सक्षम हैं, तो आप नवीनतम प्राप्त कर सकते हैं dillके साथ git+https://github.com/uqfoundation/dill.git@master#egg=dill। और आप के साथ नवीनतम जारी संस्करण प्राप्त कर सकते हैं pip install dill।
TypeError: __new__() takes at least 2 arguments (1 given)जब dillकोई ऑडियो ऑब्जेक्ट शामिल होता है, तो मैं एक जटिल चीज़ के साथ उपयोग करने की कोशिश कर रहा होता हूं (जो आशाजनक लगता है)।
TypeErrorऐसा मिल रहा है जब आप वास्तव में क्या करते हैं? यह आमतौर पर एक वर्ग उदाहरण का संकेत देते समय गलत संख्या में तर्क होने का संकेत है। यदि यह उपरोक्त प्रश्न के वर्कफ़्लो का हिस्सा नहीं है, तो क्या आप इसे एक अन्य प्रश्न के रूप में पोस्ट कर सकते हैं, इसे मुझे ईमेल पर सबमिट कर सकते हैं, या इसे dillजीथब पेज पर एक मुद्दे के रूप में जोड़ सकते हैं ?
dillमुद्दा नहीं था ।
dilएल MemoryErrorहालांकि मुझे देता है ! ऐसा करता है cPickle, pickleऔर hickle।
आप अपने लिए काम करने के लिए किसी भी प्रकार के कैश का उपयोग कर सकते हैं । यह सभी विवरणों पर विचार करता है:
pickleसंभाल करने के लिए अजगर मॉड्यूल का विस्तार करता हैlambda और सभी अच्छे अजगर विशेषताओं है।मान लें कि आपके पास एक फ़ंक्शन है myfuncजो उदाहरण बनाता है:
from anycache import anycache
class Company(object):
def __init__(self, name, value):
self.name = name
self.value = value
@anycache(cachedir='/path/to/your/cache')
def myfunc(name, value)
return Company(name, value)
एनाकाचे myfuncपहली बार कॉल cachedirकरता है और फ़ाइलनाम के रूप में एक अद्वितीय पहचानकर्ता (फ़ंक्शन के नाम और इसके तर्कों के आधार पर) का उपयोग करके एक फ़ाइल के परिणाम को अचार करता है। किसी भी लगातार चलने पर, पिक की गई वस्तु लोड हो जाती है। यदि cachedirअजगर रनों के बीच संरक्षित है, तो पिक्स्ड ऑब्जेक्ट को पिछले पायथन रन से लिया जाता है।
किसी भी अधिक जानकारी के लिए प्रलेखन देखें
anycacheसे अधिक उदाहरणों को सहेजने के लिए कोई कैसे उपयोग करेगा , classजैसे कि, या कंटेनर जैसे listकि (किसी फ़ंक्शन को कॉल करने का परिणाम नहीं था)?
company1Python3 के साथ अपने प्रश्न का उपयोग करके त्वरित उदाहरण ।
import pickle
# Save the file
pickle.dump(company1, file = open("company1.pickle", "wb"))
# Reload the file
company1_reloaded = pickle.load(open("company1.pickle", "rb"))
हालाँकि, जैसा कि इस उत्तर में कहा गया है, अचार अक्सर विफल हो जाता है। इसलिए आपको वास्तव में उपयोग करना चाहिए dill।
import dill
# Save the file
dill.dump(company1, file = open("company1.pickle", "wb"))
# Reload the file
company1_reloaded = dill.load(open("company1.pickle", "rb"))