A context manager is an object that defines the runtime context to be established when executing a with statement. The context manager handles the entry into, and the exit from, the desired runtime context for the execution of the block of code.
Let’s have a look at below example, suppose I want to calculate the Fibonacci of a number -
def fib_cal(fib_num, memo): if memo[fib_num] is not None: return memo[fib_num] elif fib_num == 1 or fib_num == 2: result = 1 else: result = fib_cal(fib_num-1, memo) + fib_cal(fib_num-2, memo) memo[fib_num] = result return result def get_fibonacci(fib_num): memo = [None] * (fib_num+1) return fib_cal(fib_num, memo) print(fibonacci(100))
RecursionError: maximum recursion depth exceeded in comparison
because the maximum recursion limit of the os has been exceeded. you can check recursion limit as follow -
import sys sys.getrecursionlimit()
So, In this kind of situation, we can use context manager which will allow us to allocate and release resources precisely when we want to. ```python import sys
class RecursionLimit: def init(self, limit): self.limit = limit self.cur_limit = sys.getrecursionlimit()
def __enter__(self): sys.setrecursionlimit(self.limit) def __exit__(self, exc_type, exc_value, exc_traceback): sys.setrecursionlimit(self.cur_limit)
MAX_LIMIT = 10000
with RecursionLimit(MAX_LIMIT): print(fibonacci(3000)) ``` Output- 4106158863079712603335683787192671052201251086373692524……..6000
__enter__() returns the resource that needs to be managed and the
__exit__() does not return anything but performs the cleanup operations.
Context-managers can be used for other purposes also like- simple file I/O, like opening and closing sockets, implementing set-up and tear-down functionality during testing.
I hope you enjoyed reading this article, If you have any suggestions on your mind, please let me know in the mail.