Cachetools for subsequent runs in python












2















Am a beginner.Sorry if my question is childish . Do cachetools in python work for susbsequent runs?



import cachetools
import time


@cachetools.cached({})
def find_sum(n):
time.sleep(5)
return n+2


print find_sum(2)
print find_sum(3)
print find_sum(2)


So during the first run the third call is faster but the next time i run the file i want the first call to be faster and take result from the cache. Can cachetools do this?










share|improve this question



























    2















    Am a beginner.Sorry if my question is childish . Do cachetools in python work for susbsequent runs?



    import cachetools
    import time


    @cachetools.cached({})
    def find_sum(n):
    time.sleep(5)
    return n+2


    print find_sum(2)
    print find_sum(3)
    print find_sum(2)


    So during the first run the third call is faster but the next time i run the file i want the first call to be faster and take result from the cache. Can cachetools do this?










    share|improve this question

























      2












      2








      2


      1






      Am a beginner.Sorry if my question is childish . Do cachetools in python work for susbsequent runs?



      import cachetools
      import time


      @cachetools.cached({})
      def find_sum(n):
      time.sleep(5)
      return n+2


      print find_sum(2)
      print find_sum(3)
      print find_sum(2)


      So during the first run the third call is faster but the next time i run the file i want the first call to be faster and take result from the cache. Can cachetools do this?










      share|improve this question














      Am a beginner.Sorry if my question is childish . Do cachetools in python work for susbsequent runs?



      import cachetools
      import time


      @cachetools.cached({})
      def find_sum(n):
      time.sleep(5)
      return n+2


      print find_sum(2)
      print find_sum(3)
      print find_sum(2)


      So during the first run the third call is faster but the next time i run the file i want the first call to be faster and take result from the cache. Can cachetools do this?







      python caching






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Jun 21 '18 at 7:19









      Savitha SureshSavitha Suresh

      618




      618
























          1 Answer
          1






          active

          oldest

          votes


















          1














          cachetools cannot do this out of the box. But it's very easy to add.



          You can pass any mutable mapping you want to the memoizing decorators. You're using a plain old dict, and dicts are trivial to pickle. And even if you use one of the fancy cache implementations provided by the library, they're all easy to pickle as well.1



          So:



          import cachetools
          import pickle
          import time

          try:
          with open('mycache.pickle', 'rb') as f:
          cache = pickle.load(f)
          except FileNotFoundError:
          cache = {} # or cachetools.LRUCache(maxsize=5) or whatever you want

          @cachetools.cached(cache)
          def find_sum(n):
          time.sleep(5)
          return n+2

          print(find_sum(2))
          print(find_sum(3))
          print(find_sum(2))

          with open('mycache.pickle', 'wb') as f:
          pickle.dump(cache, f)




          Of course you can add:




          • A finally or context manager or atexit to make sure you save your files at shutdown even if you hit an exception or ^C.

          • A timer that saves them every so often.

          • A hook on the cache object to save on every update, or every Nth update. (Just override the __setitem__ method—or see Extending cache classes for other things you can do, if you use one of the fancier classes instead of a dict.)




          Or you can even use an on-disk key-value database as a cache.



          The simplest such database is dbm. It's limited to str/bytes for both keys and values. (You can use shelve if you want non-string values; if you want non-string keys, you probably want a different solution.) So, that doesn't quite work for our example. But for a similar example, it's almost magic:



          import dbm
          import time
          import cachetools

          cache = dbm.open('mycache.dbm', 'c')
          @cachetools.cached(cache, key=lambda s:s)
          def find_string_sum(s):
          time.sleep(5)
          return s + '!'

          print(find_string_sum('a'))
          print(find_string_sum('b'))
          print(find_string_sum('a'))


          The only tricky bit was that I had to override the key function. (The default key function handles *args, **kw, so for argument 'a' you end up with something like (('a',), ()), which is obviously not a string.)





          1. As you can see from the source, there are bug fixes to make sure all of the classes are picklable in all supported Python versions, so this is clearly intentional.






          share|improve this answer

























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f50962608%2fcachetools-for-subsequent-runs-in-python%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            1














            cachetools cannot do this out of the box. But it's very easy to add.



            You can pass any mutable mapping you want to the memoizing decorators. You're using a plain old dict, and dicts are trivial to pickle. And even if you use one of the fancy cache implementations provided by the library, they're all easy to pickle as well.1



            So:



            import cachetools
            import pickle
            import time

            try:
            with open('mycache.pickle', 'rb') as f:
            cache = pickle.load(f)
            except FileNotFoundError:
            cache = {} # or cachetools.LRUCache(maxsize=5) or whatever you want

            @cachetools.cached(cache)
            def find_sum(n):
            time.sleep(5)
            return n+2

            print(find_sum(2))
            print(find_sum(3))
            print(find_sum(2))

            with open('mycache.pickle', 'wb') as f:
            pickle.dump(cache, f)




            Of course you can add:




            • A finally or context manager or atexit to make sure you save your files at shutdown even if you hit an exception or ^C.

            • A timer that saves them every so often.

            • A hook on the cache object to save on every update, or every Nth update. (Just override the __setitem__ method—or see Extending cache classes for other things you can do, if you use one of the fancier classes instead of a dict.)




            Or you can even use an on-disk key-value database as a cache.



            The simplest such database is dbm. It's limited to str/bytes for both keys and values. (You can use shelve if you want non-string values; if you want non-string keys, you probably want a different solution.) So, that doesn't quite work for our example. But for a similar example, it's almost magic:



            import dbm
            import time
            import cachetools

            cache = dbm.open('mycache.dbm', 'c')
            @cachetools.cached(cache, key=lambda s:s)
            def find_string_sum(s):
            time.sleep(5)
            return s + '!'

            print(find_string_sum('a'))
            print(find_string_sum('b'))
            print(find_string_sum('a'))


            The only tricky bit was that I had to override the key function. (The default key function handles *args, **kw, so for argument 'a' you end up with something like (('a',), ()), which is obviously not a string.)





            1. As you can see from the source, there are bug fixes to make sure all of the classes are picklable in all supported Python versions, so this is clearly intentional.






            share|improve this answer






























              1














              cachetools cannot do this out of the box. But it's very easy to add.



              You can pass any mutable mapping you want to the memoizing decorators. You're using a plain old dict, and dicts are trivial to pickle. And even if you use one of the fancy cache implementations provided by the library, they're all easy to pickle as well.1



              So:



              import cachetools
              import pickle
              import time

              try:
              with open('mycache.pickle', 'rb') as f:
              cache = pickle.load(f)
              except FileNotFoundError:
              cache = {} # or cachetools.LRUCache(maxsize=5) or whatever you want

              @cachetools.cached(cache)
              def find_sum(n):
              time.sleep(5)
              return n+2

              print(find_sum(2))
              print(find_sum(3))
              print(find_sum(2))

              with open('mycache.pickle', 'wb') as f:
              pickle.dump(cache, f)




              Of course you can add:




              • A finally or context manager or atexit to make sure you save your files at shutdown even if you hit an exception or ^C.

              • A timer that saves them every so often.

              • A hook on the cache object to save on every update, or every Nth update. (Just override the __setitem__ method—or see Extending cache classes for other things you can do, if you use one of the fancier classes instead of a dict.)




              Or you can even use an on-disk key-value database as a cache.



              The simplest such database is dbm. It's limited to str/bytes for both keys and values. (You can use shelve if you want non-string values; if you want non-string keys, you probably want a different solution.) So, that doesn't quite work for our example. But for a similar example, it's almost magic:



              import dbm
              import time
              import cachetools

              cache = dbm.open('mycache.dbm', 'c')
              @cachetools.cached(cache, key=lambda s:s)
              def find_string_sum(s):
              time.sleep(5)
              return s + '!'

              print(find_string_sum('a'))
              print(find_string_sum('b'))
              print(find_string_sum('a'))


              The only tricky bit was that I had to override the key function. (The default key function handles *args, **kw, so for argument 'a' you end up with something like (('a',), ()), which is obviously not a string.)





              1. As you can see from the source, there are bug fixes to make sure all of the classes are picklable in all supported Python versions, so this is clearly intentional.






              share|improve this answer




























                1












                1








                1







                cachetools cannot do this out of the box. But it's very easy to add.



                You can pass any mutable mapping you want to the memoizing decorators. You're using a plain old dict, and dicts are trivial to pickle. And even if you use one of the fancy cache implementations provided by the library, they're all easy to pickle as well.1



                So:



                import cachetools
                import pickle
                import time

                try:
                with open('mycache.pickle', 'rb') as f:
                cache = pickle.load(f)
                except FileNotFoundError:
                cache = {} # or cachetools.LRUCache(maxsize=5) or whatever you want

                @cachetools.cached(cache)
                def find_sum(n):
                time.sleep(5)
                return n+2

                print(find_sum(2))
                print(find_sum(3))
                print(find_sum(2))

                with open('mycache.pickle', 'wb') as f:
                pickle.dump(cache, f)




                Of course you can add:




                • A finally or context manager or atexit to make sure you save your files at shutdown even if you hit an exception or ^C.

                • A timer that saves them every so often.

                • A hook on the cache object to save on every update, or every Nth update. (Just override the __setitem__ method—or see Extending cache classes for other things you can do, if you use one of the fancier classes instead of a dict.)




                Or you can even use an on-disk key-value database as a cache.



                The simplest such database is dbm. It's limited to str/bytes for both keys and values. (You can use shelve if you want non-string values; if you want non-string keys, you probably want a different solution.) So, that doesn't quite work for our example. But for a similar example, it's almost magic:



                import dbm
                import time
                import cachetools

                cache = dbm.open('mycache.dbm', 'c')
                @cachetools.cached(cache, key=lambda s:s)
                def find_string_sum(s):
                time.sleep(5)
                return s + '!'

                print(find_string_sum('a'))
                print(find_string_sum('b'))
                print(find_string_sum('a'))


                The only tricky bit was that I had to override the key function. (The default key function handles *args, **kw, so for argument 'a' you end up with something like (('a',), ()), which is obviously not a string.)





                1. As you can see from the source, there are bug fixes to make sure all of the classes are picklable in all supported Python versions, so this is clearly intentional.






                share|improve this answer















                cachetools cannot do this out of the box. But it's very easy to add.



                You can pass any mutable mapping you want to the memoizing decorators. You're using a plain old dict, and dicts are trivial to pickle. And even if you use one of the fancy cache implementations provided by the library, they're all easy to pickle as well.1



                So:



                import cachetools
                import pickle
                import time

                try:
                with open('mycache.pickle', 'rb') as f:
                cache = pickle.load(f)
                except FileNotFoundError:
                cache = {} # or cachetools.LRUCache(maxsize=5) or whatever you want

                @cachetools.cached(cache)
                def find_sum(n):
                time.sleep(5)
                return n+2

                print(find_sum(2))
                print(find_sum(3))
                print(find_sum(2))

                with open('mycache.pickle', 'wb') as f:
                pickle.dump(cache, f)




                Of course you can add:




                • A finally or context manager or atexit to make sure you save your files at shutdown even if you hit an exception or ^C.

                • A timer that saves them every so often.

                • A hook on the cache object to save on every update, or every Nth update. (Just override the __setitem__ method—or see Extending cache classes for other things you can do, if you use one of the fancier classes instead of a dict.)




                Or you can even use an on-disk key-value database as a cache.



                The simplest such database is dbm. It's limited to str/bytes for both keys and values. (You can use shelve if you want non-string values; if you want non-string keys, you probably want a different solution.) So, that doesn't quite work for our example. But for a similar example, it's almost magic:



                import dbm
                import time
                import cachetools

                cache = dbm.open('mycache.dbm', 'c')
                @cachetools.cached(cache, key=lambda s:s)
                def find_string_sum(s):
                time.sleep(5)
                return s + '!'

                print(find_string_sum('a'))
                print(find_string_sum('b'))
                print(find_string_sum('a'))


                The only tricky bit was that I had to override the key function. (The default key function handles *args, **kw, so for argument 'a' you end up with something like (('a',), ()), which is obviously not a string.)





                1. As you can see from the source, there are bug fixes to make sure all of the classes are picklable in all supported Python versions, so this is clearly intentional.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Nov 21 '18 at 18:55









                Community

                11




                11










                answered Jun 21 '18 at 8:01









                abarnertabarnert

                256k21366465




                256k21366465
































                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f50962608%2fcachetools-for-subsequent-runs-in-python%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    這個網誌中的熱門文章

                    Academy of Television Arts & Sciences

                    L'Équipe

                    1995 France bombings