import time56 Context Manager (Custom)
56.1 @contextmanager Decorator
56.1.1 file_manager()
import time
from contextlib import contextmanager
from typing import Generator, IO, Any@contextmanager
def file_manager(path: str, mode: str) -> Generator[IO, Any, None]:
file: IO = open(path, mode)
print('Opening file...')
try:
yield file
finally:
print('Closing file...')
if file:
file.close()with file_manager("hello.txt", mode="r") as f:
raise Exception("something bad happens!")
print(f.read())Opening file...
Closing file...
--------------------------------------------------------------------------- Exception Traceback (most recent call last) Cell In[6], line 2 1 with file_manager("hello.txt", mode="r") as f: ----> 2 raise Exception("something bad happens!") 3 print(f.read()) Exception: something bad happens!
56.1.2 timer() ⭐️
import time
from contextlib import contextmanager
from typing import Generator, IO, Any@contextmanager
def timer():
"""Context manager for measuring execution time.
Returns
-------
callable
A lambda function that returns the elapsed time
Example
-------
```python
with timer() as t:
# some code to measure
pass
t = t()
t # prints elapsed time
```
"""
start_time: float = time.perf_counter()
try:
yield lambda: elapsed
finally:
elapsed = time.perf_counter() - start_time
print(f'Time: {elapsed:.4f}s')with timer() as t:
text = ""
for i in range(100_000):
text += str(i)Time: 0.3740s
t()0.3740487500326708
56.1.3 timer() start & end
from datetime import datetime
@contextmanager
def timer2():
start_time: float = time.perf_counter()
print(f"Started at: {datetime.now():%H:%M:%S}")
try:
yield lambda: elapsed
finally:
elapsed = time.perf_counter() - start_time
print(f"Ended at: {datetime.now():%H:%M:%S}")
print(f'Time: {elapsed:.4f}s')with timer2() as t2:
text = ""
for i in range(100_000):
text += str(i)Started at: 16:36:24
Ended at: 16:36:24
Time: 0.3461s
56.2 Timer Class
class Timer:
def __init__(self, name: str):
self.name = name
def __enter__(self):
self._start_time = time.perf_counter()
print(f"Starting timer for {self.name}")
return self
def __exit__(self, exc_type, exc_value, traceback):
self._end_time = time.perf_counter()
elapsed_time = self._end_time - self._start_time
print(f"Timer for {self.name} finished. Elapsed time: {elapsed_time:.4f} seconds")with Timer("for...loop timer") as timer:
print(timer.name)
for _ in range(1000000):
passStarting timer for for...loop timer
for...loop timer
Timer for for...loop timer finished. Elapsed time: 0.0449 seconds