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))
Output- 354224848179261915075
print(fibonacci(3000))
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
The __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.