Skip to main content

A decorator for adding memoization to functions and methods.

Project description

Memoiz

A decorator for adding memoization to functions and methods.

Introduction

Memoiz provides a function decorator that adds memoization to a function or method. It makes reasonable assumptions about how and if to cache the return value of a function or method based on the arguments passed to it.

Features

  • Use the Memoiz decorator on functions and methods.
  • A thread-safe cache.
  • Use any number of arguments or keyword arguments.
  • Support for parameter and return type hints.
  • Handles circular references in dictionaries, lists, sets, and tuples.
  • Support for common unhashable types (e.g., dict, list, set).
  • Selective cache entry removal.

Table of Contents

Installation

pip install memoiz

Usage

Apply Memoization to Class Methods

In this example you will use Memoiz to memoize the return value of the greeter.greet method and print the greeting.

from memoiz import Memoiz

# `cache` is a Python decorator and a callable.
cache = Memoiz()


class Greeter:

    def __init__(self):
        self.adv = "Very"

    @cache # The `cache` decorator adds memoization capabilities to the `greet` method.
    def greet(self, adj: str) -> str:
        return f"Hello, {self.adv} {adj} World!"


greeter = Greeter()

print("1:", cache._cache)

greeting = greeter.greet("Happy")

print("2:", greeting)
1: {}
2: Hello, Very Happy World!

As a continuation of the example, you will selectively clear cached articles using the cache.clear method.

greeter = Greeter()

print("1:", cache._cache)

greeting = greeter.greet("Happy")

print("2:", greeting)

greeting = greeter.greet("Cautious")

print("3:", greeting)

# The cache has memoized the two method calls.
print("4:", cache._cache)

# Clear the call to `greeter.greet` with the "Happy" argument.
#                          ⮶ args
cache.clear(greeter.greet, "Happy")
#                   ⮴ method

print("5:", cache._cache)

# Clear the call to `greeter.greet` with the `Cautious` argument.
cache.clear(greeter.greet, "Cautious")

# The cache is empty.
print("6:", cache._cache)
1: {}
2: Hello, Very Happy World!
3: Hello, Very Cautious World!
4: {<bound method Greeter.greet of <__main__.Greeter object at 0x7f486842fbe0>>: {(('Happy',), ()): 'Hello, Very Happy World!', (('Cautious',), ()): 'Hello, Very Cautious World!'}}
5: {<bound method Greeter.greet of <__main__.Greeter object at 0x7f486842fbe0>>: {(('Cautious',), ()): 'Hello, Very Cautious World!'}}
6: {}

Apply Memoization to Functions

In this example you will use Memoiz to memoize the return value of the greet function and print the greeting.

from memoiz import Memoiz

cache = Memoiz()


@cache
def greet(adj: str) -> str:
    return f"Hello, {adj} World!"


print("1:", cache._cache)

greeting = greet("Happy")

print("2:", greeting)
1: {}
2: Hello, Happy World!

As a continuation of the example, you will selectively clear cached articles using the cache.clear method.

print("1:", cache._cache)

greeting = greet("Happy")

print("2:", greeting)

greeting = greet("Cautious")

print("3:", greeting)

print("4:", cache._cache)

#                  ⮶ args
cache.clear(greet, "Happy")
#           ⮴ function

# The cached call using the "Happy" argument is deleted; however, the call using the "Cautious" is still present.
print("5:", cache._cache)

#                  ⮶ args
cache.clear(greet, "Cautious")
#           ⮴ function

# The cache is now empty.
print("6:", cache._cache)
1: {}
2: Hello, Happy World!
3: Hello, Cautious World!
4: {<function greet at 0x7f486842bd00>: {(('Happy',), ()): 'Hello, Happy World!', (('Cautious',), ()): 'Hello, Cautious World!'}}
5: {<function greet at 0x7f486842bd00>: {(('Cautious',), ()): 'Hello, Cautious World!'}}
6: {}

Memoization Strategy

Memoiz will attempt to recursively transform a callable's arguments into a hashable key. The key is used in order to index and look up the callable's return value. The strategy that Memoiz employs for key generation depends on the type of the argument(s) passed to the callable. The Type Transformations table provides examples of how Memoiz transforms arguments of common types.

Type Transformations

Type Example Hashable Type Hashable Representation
dict {'b':42, 'c': 57, 'a': 23} tuple of tuples (('a', 23), ('b', 42), ('c', 57))
list [23, 42, 57] tuple (23, 42, 57)
tuple (23, 42, 57) tuple (23, 42, 57)
set {23, 42, 57} tuple (23, 42, 57)
hashable types hash(...) tuple (Ellipsis,)

NB Dictionaries are sorted by their keys prior to indexing the callable's return value.

API

The Memoiz Class

memoiz.Memoiz(sequentials, mapables, deep_copy)

  • sequentials Tuple[type, ...] An optional tuple of types that are assumed to be sequence-like. Default (list, tuple, set)
  • mapables Tuple[type, ...] An optional tuple of types that are assumed to be dict-like. Default (dict,)
  • deep_copy bool Optionally return the cached return value using Python's copy.deepcopy. This can help prevent mutations of the cached return value. Default: True.

memoiz.__call__(callable)

  • callable typing.Callable The function or method for which you want to add memoization.

A Memoiz instance (see above) is a callable. This is the @cache decorator that is used in order to add memoization to a callable. Please see the above usage for how to use this decorator.

memoiz.clear(callable, *args, **kwargs)

  • callable typing.Callable The callable.
  • args Any The arguments passed to the callable.
  • kwargs Any The keyword arguments passed to the callable.

Clears the cache for the specified callable and arguments. See the usage for for how to clear the cache.

memoiz.clear_all()

Resets the cache making items in the old cache potentially eligible for garbage collection.

Test

Clone the repository.

git clone https://github.com/faranalytics/memoiz.git

Change directory into the root of the repository.

cd memoiz

Run the tests.

python tests/test.py -v

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

memoiz-2.0.4.tar.gz (7.4 kB view details)

Uploaded Source

Built Distribution

memoiz-2.0.4-py3-none-any.whl (5.9 kB view details)

Uploaded Python 3

File details

Details for the file memoiz-2.0.4.tar.gz.

File metadata

  • Download URL: memoiz-2.0.4.tar.gz
  • Upload date:
  • Size: 7.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-httpx/0.27.2

File hashes

Hashes for memoiz-2.0.4.tar.gz
Algorithm Hash digest
SHA256 6bbdda628dc4e904abf557356b78f7617e79d9acc6b00e93a35e55f24256b053
MD5 d16bbc572862759c8c7bc12a24dafdac
BLAKE2b-256 7f53ff2b0855e2c9367e01be874ef6930493f99d645ed2939d463d89a70d982d

See more details on using hashes here.

File details

Details for the file memoiz-2.0.4-py3-none-any.whl.

File metadata

  • Download URL: memoiz-2.0.4-py3-none-any.whl
  • Upload date:
  • Size: 5.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-httpx/0.27.2

File hashes

Hashes for memoiz-2.0.4-py3-none-any.whl
Algorithm Hash digest
SHA256 f82186d66ceaa532cf061a6300dd55b5ec8b13e78025e3536ff014c7ed78d94b
MD5 3c501c25075172e862b3cde3bdd60b1e
BLAKE2b-256 212f069cc636779870eebbbedb433b360cf966f1c392fa7cc2c653c4d61ea54b

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page