What is the main difference between the two? I have been studying Python and came across them. A decorator is essentially a function that wraps another function and you can do anything before and after a particular function executes.
def my_decorator(some_function):
def wrapper(*args, **kwargs):
print("Do something before the function is called")
some_function(*args, **kwargs)
print("Do something after the function is called")
return wrapper
@my_decorator
def addition(a, b):
result = a+b
print("Addition of {} and {} is {}".format(a,b,result))
But after studying Context Manager, I couldn't help but notice that it too has a enter and exit where you could do most similar operations.
from contextlib import contextmanager
@contextmanager
def open_file(path, mode):
the_file = open(path, mode)
yield the_file
the_file.close()
files = []
for x in range(100000):
with open_file('foo.txt', 'w') as infile:
files.append(infile)
for f in files:
if not f.closed:
print('not closed')
Everything before yield is taken as part of the "enter" and everything after a part of "exit".
Although both Context Managers and Decorators are syntactically different, their behaviors can be looked upon as similar. So what is the difference? What are the different scenarios when one should use either of them?
They are completely separate concepts and should not be seen in the same light.
A decorator lets you augment or replace a function or a class when it is defined. This is far broader than just executing things before or after a function call. Sure, your specific decorator lets you do something just before and after a function call, provided no exception is raised, or you explicitly handle exceptions. But you could also use a decorator to add an attribute to the function object, or to update some kind of registry. Or to return something entirely different and ignore the original function. Or to produce a wrapper that manipulates the arguments passed in, or the return value of the original function. A context manager can't do any of those things.
A context manager on the other hand lets you abstract away try: ... finally:
constructs, in that no matter how the block exits, you get to execute some more code at the end of the block. Even if the block raises an exception, or uses return
to exit a function, the context manager __exit__
method is still going to be called, regardless. A context manager can even suppress any exceptions raised in the block.
The two concepts are otherwise not related at all. Use decorators when you require to do something to or with functions or classes when they are defined. Use context managers when you want to clean up or take other actions after a block ends.
they are completely different concepts.
context managers are objects to be used with the python with
keyword. It runs code when entering the block and exiting the block.
decorators are modifications to a function or class definition. It runs code that replaces the function as it is being defined.
@D
def Y(...):
...
is just another way of writing
def Y(...):
....
Y = D(Y)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With