क्या एक पायथन कैशिंग लाइब्रेरी है?


123

मैं एक पायथन कैचिंग लाइब्रेरी की तलाश कर रहा हूं, लेकिन अभी तक कुछ भी नहीं मिला। मुझे एक सरल dict-प्रकार के इंटरफ़ेस की आवश्यकता है जहां मैं चाबियाँ और उनकी समाप्ति निर्धारित कर सकता हूं और उन्हें वापस कैश कर सकता हूं। कुछ इस तरह की तरह:

cache.get(myfunction, duration=300)

जो मुझे कैश से आइटम देगा यदि यह मौजूद है या फ़ंक्शन को कॉल करता है और इसे स्टोर करता है यदि यह समाप्त नहीं हुआ है या समाप्त हो गया है। किसी को इस तरह से कुछ पता है?


मुझे लगता है कि आप itemअपने उदाहरण में याद कर रहे हैं ।
साइलेंटगॉस्ट

हाँ, यह शायद एक कुंजी की आवश्यकता होगी ... और, 2.x.
स्टावरोस कोरोकिथिक

3
एक ही प्रक्रिया के भीतर या प्रक्रियाओं के बीच साझा? पिरोया या नहीं?
आरोन वॉटर्स

1
यह धागा-सुरक्षित होना चाहिए, माफ करना, मुझे उल्लेख करना चाहिए था। मुझे प्रक्रियाओं के बीच साझा करने की आवश्यकता नहीं है।
स्टावरोस कोरोकिथेकिस

6
DiskCache का प्रयास करें : Apache2 लाइसेंस, 100% कवरेज, थ्रेड-सुरक्षित, प्रक्रिया-सुरक्षित, एकाधिक निष्कासन नीतियाँ और तेज़ (मानक)
ग्रांटज

जवाबों:


52

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

7
डॉगपाइल भी देखें - माना जाता है कि नया और बेहतर बीकर।
s29

72

पाइथन 3.2 से आप डेकोरेटर लाइब्रेरी से डेकोरेटर @lru_cache का उपयोग कर सकते हैं । यह एक अंतिम हाल ही में उपयोग किया गया कैश है, इसलिए इसमें आइटम के लिए कोई समय समाप्ति समय नहीं है, लेकिन एक तेज़ हैक के रूप में यह बहुत उपयोगी है।

from functools import lru_cache

@lru_cache(maxsize=256)
def f(x):
  return x*x

for x in range(20):
  print f(x)
for x in range(20):
  print f(x)

20
cachetools इनमें से एक अच्छा कार्यान्वयन प्रदान करता है और यह संगत अजगर 2 और अजगर 3 है
vaab

1
cachetools के लिए बड़ा +1 ... बहुत अच्छा लगता है और कुछ और कैशिंग एल्गोरिदम :) है
Jörn Hees

यह कभी भी सुझाव नहीं दिया जाना चाहिए! संगत रहो।
पास्कलवीकूटेन

1
थ्रेड सुरक्षित नहीं होने के बारे में आपकी टिप्पणी से @roboslone, दो साल (माइनस 4 दिन ..)। मेरे पास cachetools 2.0.0 है और मैं कोड में देखता हूं कि यह एक RLock का उपयोग करता है। /usr/lib/python2.7/site-packages/cachetools/func.py
Motty

@ मैटी: कैचेथल्स 4.0.0.0 के लिए प्रलेखन यह कहता है: "कृपया ध्यान रखें कि ये सभी कक्षाएं थ्रेड-सुरक्षित हैं । कई थ्रेड्स से साझा कैश तक पहुँच को ठीक से सिंक्रनाइज़ किया जाना चाहिए, जैसे कि मेमोइज़िंग डेकोरेटर विशेषज्ञों में से एक का उपयोग करके। उपयुक्त ताला वस्तु "(बोल्ड मेरा)
मार्टीन्यू

28

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


यह चालाकी है। कुछ बदलाव और डेकोरेटर निर्धारित समय के बाद भी समाप्त हो सकता है।
एहतेश चौधरी

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

14

Joblib https://joblib.readthedocs.io मेमोइज़ पैटर्न में कैशिंग कार्यों का समर्थन करता है। ज्यादातर, विचार कम्प्यूटेशनल रूप से महंगे कार्यों को कैश करने के लिए है।

>>> from joblib import Memory
>>> mem = Memory(cachedir='/tmp/joblib')
>>> import numpy as np
>>> square = mem.cache(np.square)
>>> 
>>> a = np.vander(np.arange(3)).astype(np.float)
>>> b = square(a)                                   
________________________________________________________________________________
[Memory] Calling square...
square(array([[ 0.,  0.,  1.],
       [ 1.,  1.,  1.],
       [ 4.,  2.,  1.]]))
___________________________________________________________square - 0...s, 0.0min

>>> c = square(a)

आप फंक्शनल चीजें भी कर सकते हैं जैसे फंक्शंस पर @ memory.cache डेकोरेटर का इस्तेमाल करना। दस्तावेज यहाँ है: https://joblib.readthedocs.io/en/latest/generated/joblib.Morory.html


2
एक सिडेनोट के रूप में, जॉबलिब वास्तव में चमकता है जब आप बड़े न्यूमपी सरणियों के साथ काम कर रहे होते हैं, क्योंकि इसमें विशेष रूप से उनसे निपटने के लिए विशेष तरीके होते हैं।
alexbw

12

अभी तक किसी ने भी आश्रय का उल्लेख नहीं किया है। https://docs.python.org/2/library/shelve.html

यह ज्ञापन नहीं है, लेकिन बहुत सरल दिखता है और आपकी आवश्यकता के अनुरूप हो सकता है।


मैंने मानक शेल्व मॉड्यूल के लिए एक थ्रेड- और मल्टीप्रोसेस-सेफ रैपर लिखा था (http अनुरोधों को कैशिंग करने के लिए एक हेल्पर फ़ंक्शन सहित) जो किसी के लिए भी उपयोगी है: github.com/cristoper/shelfcache
cristoper

9

मुझे लगता है कि अजगर मेमकाटेड एपीआई प्रचलित उपकरण है, लेकिन मैंने इसे खुद इस्तेमाल नहीं किया है और मुझे यकीन नहीं है कि यह उन विशेषताओं का समर्थन करता है जो आपको चाहिए।


3
यह एक उद्योग मानक है, लेकिन मैं चाहता हूं कि एक सरल इन-मेमोरी स्टोरेज मैकेनिज्म है जो 100 कुंजी या तो पकड़ सकता है, और मेमेकैक्ड थोड़ा ओवरकिल है। उत्तर के लिए धन्यवाद, यद्यपि।
स्टावरोस कोरोकिथकिस

7
import time

class CachedItem(object):
    def __init__(self, key, value, duration=60):
        self.key = key
        self.value = value
        self.duration = duration
        self.timeStamp = time.time()

    def __repr__(self):
        return '<CachedItem {%s:%s} expires at: %s>' % (self.key, self.value, time.time() + self.duration)

class CachedDict(dict):

    def get(self, key, fn, duration):
        if key not in self \
            or self[key].timeStamp + self[key].duration < time.time():
                print 'adding new value'
                o = fn(key)
                self[key] = CachedItem(key, o, duration)
        else:
            print 'loading from cache'

        return self[key].value



if __name__ == '__main__':

    fn = lambda key: 'value of %s  is None' % key

    ci = CachedItem('a', 12)
    print ci 
    cd = CachedDict()
    print cd.get('a', fn, 5)
    time.sleep(2)
    print cd.get('a', fn, 6)
    print cd.get('b', fn, 6)
    time.sleep(2)
    print cd.get('a', fn, 7)
    print cd.get('b', fn, 7)

5
मैंने ऐसा कुछ किया है, लेकिन आपको असीम रूप से बढ़ने से बचने के लिए मल्टीथ्रेडिंग और एक आकार पैरामीटर के लिए ताले की आवश्यकता है। फिर आपको कम-से-पहुंच वाले, आदि आदि को त्यागने के लिए चाबियों को छांटने के लिए कुछ फ़ंक्शन की आवश्यकता होती है ...
Stavros Korokithakis

रेपर लाइन सही नहीं है (self.timeStamp का उपयोग करना चाहिए)। इसके साथ ही यह एक खराब क्रियान्वयन है जो अनावश्यक रूप से हर प्राप्त () के लिए गणित करता है। समाप्ति समय की गणना कैश्ड इमिट में की जानी चाहिए।
20

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

6

आप समस्या के लिए मेरे सरल समाधान का उपयोग कर सकते हैं। यह वास्तव में सीधा है, कुछ भी नहीं फैंसी:

class MemCache(dict):
    def __init__(self, fn):
        dict.__init__(self)
        self.__fn = fn

    def __getitem__(self, item):
        if item not in self:
            dict.__setitem__(self, item, self.__fn(item))
        return dict.__getitem__(self, item)

mc = MemCache(lambda x: x*x)

for x in xrange(10):
    print mc[x]

for x in xrange(10):
    print mc[x]

यह वास्तव में समाप्ति funcionality की कमी है, लेकिन आप आसानी से MemCache c-tor में एक विशेष नियम को निर्दिष्ट करने के साथ इसे बढ़ा सकते हैं।

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

आशा करता हूँ की ये काम करेगा


1
कुछ सरल सुझाने के लिए +1। समस्या के आधार पर, यह सिर्फ काम का साधन हो सकता है। PS आपको इसकी आवश्यकता नहीं elseहै __getitem__:)
hiwaylon

उसे elseमें करने की आवश्यकता क्यों नहीं होगी __getitem__? यही वह जगह है जहां वह तानाशाह ...
निल्स ज़ेहन

5

रेडिस की कोशिश करें, यह एक परमाणु तरीके से डेटा साझा करने के लिए या यदि आपको कुछ वेब साइट प्लेटफ़ॉर्म मिला है, तो अनुप्रयोगों के लिए यह सबसे साफ और आसान समाधान है। इसकी स्थापना के लिए बहुत आसान है, आपको एक अजगर रेडिस क्लाइंट की आवश्यकता होगी http://pypi.python.org/pypi/redis


1
उल्लेख किया जाना चाहिए, यह प्रक्रिया से बाहर है, टीसीपी का उपयोग करने की आवश्यकता है।
जेफ्री कॉप्स


2

इस परियोजना का उद्देश्य "मनुष्यों के लिए कैशिंग" प्रदान करना है (ऐसा लगता है कि हालांकि यह काफी अज्ञात है)

परियोजना पृष्ठ से कुछ जानकारी:

स्थापना

पाइप स्थापित कैश

उपयोग:

import pylibmc
from cache import Cache

backend = pylibmc.Client(["127.0.0.1"])

cache = Cache(backend)

@cache("mykey")
def some_expensive_method():
    sleep(10)
    return 42

# writes 42 to the cache
some_expensive_method()

# reads 42 from the cache
some_expensive_method()

# re-calculates and writes 42 to the cache
some_expensive_method.refresh()

# get the cached value or throw an error
# (unless default= was passed to @cache(...))
some_expensive_method.cached()


-5

कीरिंग सबसे अच्छा अजगर कैशिंग लाइब्रेरी है। आप उपयोग कर सकते हैं

keyring.set_password("service","jsonkey",json_res)

json_res= keyring.get_password("service","jsonkey")

json_res= keyring.core.delete_password("service","jsonkey")

यह एक कीरिंग लाइब्रेरी है, कैशिंग लाइब्रेरी नहीं।
स्टावरोस कोरोकिथिस

असल में @StavrosKorokithakis, मैं कीरिंग के माध्यम से चाबियों का कैशिंग कार्यान्वित
छोटा सा भूत
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.