2013-03-23 2 views
11

मैं पाइथन 3.3 में @functools.lru_cache का उपयोग कर रहा हूं। प्रोग्राम को पुनरारंभ होने पर इसे पुनर्स्थापित करने के लिए, मैं कैश को फ़ाइल में सहेजना चाहता हूं। मैं कैसे कर सकता हूँपाइथन में फ़ाइल functools.lru_cache में कैश को स्टोर करें> = 3.2

संपादित करें 1 संभव समाधान: We need to pickle any sort of callable

समस्या नमकीन बनाना __closure__:

_pickle.PicklingError: Can't pickle <class 'cell'>: attribute lookup builtins.cell failed 

अगर मैं इसके बिना समारोह बहाल करने की कोशिश, मैं मिलता है:

TypeError: arg 5 (closure) must be tuple 
+4

नोट मुझे लगता है कि LRU कैश कार्यान्वयन अजगर 3.4 या 3.5 में एक सी कार्यान्वयन द्वारा प्रतिस्थापित किया जा रहा है, कैश सामग्री निकालने पर किसी भी प्रयास है शायद भविष्य के सबूत होने वाला नहीं है। –

+0

@MartijnPieters: जानकारी के लिए धन्यवाद। –

+2

बस 'lru_cache' से बचें। क्या आपके फ़ंक्शन के लिए 'lru_cache' या एक साधारण कैश होना महत्वपूर्ण है? अन्यथा आप 'lru_cache' को फिर से कार्यान्वित कर सकते हैं और अपनी इच्छित कार्यक्षमता जोड़ सकते हैं। – Bakuriu

उत्तर

10

आप lru_cache का उपयोग करके जो भी करना चाहते हैं वह नहीं कर सकते हैं, क्योंकि यह कैश तक पहुंचने के लिए एपीआई प्रदान नहीं करता है, और इसे भविष्य में रिलीज़ में सी में फिर से लिखा जा सकता है। यदि आप वास्तव में कैश को सहेजना चाहते हैं तो आपको एक अलग समाधान का उपयोग करना होगा जो आपको कैश तक पहुंच प्रदान करता है।

अपने आप को कैश लिखना काफी आसान है। उदाहरण के लिए:

from functools import wraps 

def cached(func): 
    @wraps(func) 
    def wrapper(*args): 
     try: 
      return func.cache[args] 
     except KeyError: 
      func.cache[args] = result = func(*args) 
      return result 
    wrapper.cache = {} 
    return wrapper 

फिर आप यह एक डेकोरेटर के रूप में आवेदन कर सकते हैं:

>>> @cached 
... def fibonacci(n): 
...  if n < 2: 
...    return n 
...  return fibonacci(n-1) + fibonacci(n-2) 
... 
>>> fibonacci(100) 
354224848179261915075L 

और पुनः प्राप्त cache:

>>> fibonacci.cache 
{(32,): 2178309, (23,): 28657, ... } 

आप कर सकते हैं तो अचार/कैश unpickle आप कृपया के रूप में और इसे लोड करें:

fibonacci.cache = pickle.load(cache_file_object) 

मुझे पाइथन के अंक ट्रैकर में lru_cache पर डंप/लोड जोड़ने के लिए मिला, लेकिन इसे स्वीकार/कार्यान्वित नहीं किया गया था। शायद भविष्य में lru_cache के माध्यम से इन परिचालनों के लिए अंतर्निहित समर्थन होना संभव होगा।

+1

कोड के लिए धन्यवाद, मैं कोशिश करूँगा, मुझे लगता है कि यह एक अच्छा समाधान हो सकता है। मैं सुविधा अनुरोध का निर्माता हूं;) तिथि को देखें। –

+0

सटीक उपयोग के मामले के आधार पर, [शेल्फ] (https://docs.python.org/3.5/library/shelve.html) के साथ कैश बनाने के लायक हो सकता है, जो मूल रूप से लगातार डिक्ट्स हैं। –

+0

यह वास्तव में काम नहीं करता है! आप कैश को डिस्क के साथ डिस्क पर सहेज सकते हैं - लेकिन उन्हें बताए गए अनुसार काम नहीं करता है। – Nudin

1

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

+0

आंतरिक बहुत मुश्किल हैं।मैं बस उन्हें संपादित कर सकता हूं और कैश का पर्दाफाश कर सकता हूं, लेकिन यदि संभव हो, तो डिफ़ॉल्ट पुस्तकालयों को बदलने के लिए मैं पसंद करता हूं। –

+0

@ फ्रांसेस्कोफ्रासिनेली मेरा मतलब था कि आप कार्यान्वयन को अपने पेंट में कॉपी कर सकते हैं और इसे बदल सकते हैं। – wRAR

+0

हाँ, मुझे मिल गया। फ़ंक्शन (मार्शल?) निर्यात करने या केवल कैश (निरीक्षण?) को निर्यात करने और आयात करने का कोई तरीका मौजूद नहीं है। –

4

डिस्क पर लगातार कैशिंग के लिए joblib.Memory का उपयोग करने पर विचार करें।

चूंकि डिस्क बहुत बड़ी है, एलआरयू कैशिंग योजना की कोई आवश्यकता नहीं है।

1

आप मेरा एक पुस्तकालय का उपयोग कर सकते, mezmorize

import random 
from mezmorize import Cache 

cache = Cache(CACHE_TYPE='filesystem', CACHE_DIR='cache') 


@cache.memoize() 
def add(a, b): 
    return a + b + random.randrange(0, 1000) 

>>> add(2, 5) 
727 
>>> add(2, 5) 
727 
+1

अच्छा काम करता है, लेकिन 'CHCHE_DIR के आसपास' नहीं होना चाहिए। दुर्भाग्यवश, संपादन केवल कम से कम 6 वर्णों के साथ संभव है .... – koalo

संबंधित मुद्दे