Pythonのlru_cacheはキャッシュ機構を提供します.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from functools import lru_cache


@lru_cache
def fib(n):
    if n in (0, 1):
        return n
    else:
        return fib(n - 1) + fib(n - 2)


if __name__ == '__main__':
    print(fib(3))   # => 2
    print(fib(100)) # => 354224848179261915075

これは一瞬で返ってきます.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from functools import lru_cache


@lru_cache(maxsize=1)
def get_number(n):
    print("get number is called")
    return n


print(get_number(2)) # => get number is called\n2
print(get_number(2)) # => 2
print(get_number(3)) # => get number is called\n3
print(get_number(3)) # => 3
print(get_number(2)) # => get number is called\n2

これを利用すると 簡単にシングルトンを実現できます.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from functools import lru_cache


@lru_cache(maxsize=1)
def get_number():
    print("get number is called")
    return 100


print(get_number())  # => get number is called\n100
print(get_number())  # => 100