python-dependency-injector icon indicating copy to clipboard operation
python-dependency-injector copied to clipboard

Cached Value

Open str-it opened this issue 1 year ago • 1 comments
trafficstars

I want to have a Singleton which functions as a cache for a method call.

I want the field file_content in my container be initialized one time by calling a given method (reader.read). From then on always that result should be returned instead of calling the method again.

I have added a working code example below. Is there any better way? Maybe it might be useful if it was rewritten as a new Provider?

from pathlib import Path
from dependency_injector import containers, providers


class Reader:
    def read(self, filepath: Path, *args, **kwargs) -> str:
        print('read file')
        print('args:', args)
        print('kwargs:', kwargs)
        print()
        return filepath.read_text('utf-8')


SingletonAsCache = lambda bound_method, *args, **kwargs: bound_method(*args, **kwargs)


class MyContainer(containers.DeclarativeContainer):
    reader = providers.Factory(Reader)

    file_content = providers.Singleton(SingletonAsCache, reader.provided.read)


container = MyContainer()


def print_first_line():
    c: str = container.file_content(Path(__file__), 'any arg', any_kwarg='any_kwarg_value')
    print('first line:', c.splitlines()[0])


print_first_line()
print_first_line()
print_first_line()

Output:

read file
args: ('any arg',)
kwargs: {'any_kwarg': 'any_kwarg_value'}

first line: from pathlib import Path
first line: from pathlib import Path
first line: from pathlib import Path

str-it avatar Sep 26 '24 11:09 str-it