On Thursday, September 29th, 2022 at 07:18, Robert Latest via Python-list <python-list@python.org> wrote:
> Hi Chris and dh, > > thanks for your --as usually-- thoughtful and interesting answers. Indeed, > when > doing these web applications I find that there are several layers of useful, > maybe less useful, and unknown caching. Many of my requests rely on a > notoriously unreliable read-only database outside of my control, so I cache > the > required data into a local DB on my server, then I do some in-memory caching > of > expensive data plots because I haven't figured out how to reliably exploit the > client-side caching ... then every middleware on that path may or may not > implement its own version of clever or not-so-clever caching. Probably not a > good idea to try and outsmart that by adding yet another thing that may break > or not be up-to-date at the wrong moment. > > That said, the only caching that SQLAlchemy does (to my knowledge) is that it > stores retrieved DB items by their primary keys in the session. Not worth much > since the session gets created and dumped on each request by SQA's unit of > work > paradigm. But the DB backend itself may be caching repeated queries. > > Back to Python-theory: The "Cloak" object is the only way I could think of to > sneak changing data past lru_cache's key lookup mechanism. Is there some other > method? Just curious. > > -- > https://mail.python.org/mailman/listinfo/python-list You could use closures. For example, something like this: import functools import time def my_cache(timeout): start = time.monotonic() def cache_decorator(func): wrapper = _my_cache_wrapper(func, timeout, start) return functools.update_wrapper(wrapper, func) return cache_decorator def _my_cache_wrapper(func, timeout, start): first = None @functools.cache def _cached(timeout_factor, *args): print("In the _cached function") return func(first, *args) def wrapper(*args): print("In the wrapper") nonlocal first first, *rest = args elapsed = time.monotonic() - start timeout_factor = elapsed // timeout return _cached(timeout_factor, *rest) return wrapper @my_cache(3) def expensive(first, second, third): print("In the expensive function") return (first, second, third) if __name__ == "__main__": print(expensive(1, 2, 3)) print() time.sleep(2) print(expensive(2, 2, 3)) print() time.sleep(2) print(expensive(3, 2, 3)) This should output the following: In the wrapper In the _cached function In the expensive function (1, 2, 3) In the wrapper (1, 2, 3) In the wrapper In the _cached function In the expensive function (3, 2, 3) It's not necessarily better than your version though. :D Kind regards, Heinrich Kruger -- https://mail.python.org/mailman/listinfo/python-list