Why is the calculated time returned in the __enter__ method using context manager in python?
Question:
# timing.py
from time import perf_counter
class Timer:
def __enter__(self):
self.start = perf_counter()
self.end = 0.0
return lambda: self.end - self.start # Does it not evaluate to 0.0 - self.start???
def __exit__(self, *args):
self.end = perf_counter()
With Timer() as time:
# do something
print(time())
In the above code, according to me, the return statement should be placed in the __exit__()
method as it hold the true value of the end time.
I know that the __enter__()
method is called once at the beginning of the with
block, so it should hold the starting time. Logically it makes sense to me that the __exit__()
, which is also called once, can calculate the ending time and then return the elapsed time.
The above code gives me the impression that the __enter__()
method is called twice.
Kindly provide me clarity on what is going on.
Answers:
The value returned by the __enter__
method is assigned to the as ...
variable. So in the example you give, the variable time
will be assigned the lambda expression.
Lambda expressions are functions. They are not immediately evaluated.
So at the time your code calls time()
, both self.start
and self.end
have values assigned by __enter__
and __exit__
, respectively. Calling time()
will calculate and return the difference between the start time and the end time.
# timing.py
from time import perf_counter
class Timer:
def __enter__(self):
self.start = perf_counter()
self.end = 0.0
return lambda: self.end - self.start # Does it not evaluate to 0.0 - self.start???
def __exit__(self, *args):
self.end = perf_counter()
With Timer() as time:
# do something
print(time())
In the above code, according to me, the return statement should be placed in the __exit__()
method as it hold the true value of the end time.
I know that the __enter__()
method is called once at the beginning of the with
block, so it should hold the starting time. Logically it makes sense to me that the __exit__()
, which is also called once, can calculate the ending time and then return the elapsed time.
The above code gives me the impression that the __enter__()
method is called twice.
Kindly provide me clarity on what is going on.
The value returned by the __enter__
method is assigned to the as ...
variable. So in the example you give, the variable time
will be assigned the lambda expression.
Lambda expressions are functions. They are not immediately evaluated.
So at the time your code calls time()
, both self.start
and self.end
have values assigned by __enter__
and __exit__
, respectively. Calling time()
will calculate and return the difference between the start time and the end time.